Search code examples
c#if-statementwhile-loop

Trying to iterate depending on key input using a while loop with if / else if


I have a code block to validate what a user inputs, using the keyboard...

Mainly asking for UP/DOWN/LEFT/RIGHT arrow keys...

When pressing up, it should increase the value of the counter by 1. When pressing down, it should decrease the value by 1.

However,

It does not evaluate all key presses and only the first one.

So, if I choose to press Down. it will only continue to decrease no matter if I later on change my input from Down to Up.

Here is the snippet that needs to be modified.

Point p1 = new Point(5, 2);
ConsoleKeyInfo input = Console.ReadKey();
while (Console.ReadKey().Key != ConsoleKey.Escape)
        {
            if (input.Key == ConsoleKey.UpArrow)
            {
                p1.Y++;
                Console.WriteLine(p1.Y);
            } else if (input.Key == ConsoleKey.DownArrow)
            {
                p1.Y--;
                Console.WriteLine(p1.Y);
            } else if (input.Key == ConsoleKey.LeftArrow)
            {
                p1.X--;
                Console.WriteLine(p1.X);
            } else if (input.Key == ConsoleKey.RightArrow)
            {
                p1.X++;
                Console.WriteLine(p1.X);
            }
        }

I want to increase/decrease value depending on which key is pressed: If pressing left, it should go minus -1 each time I press left. I should be able to change the input anytime I want to.

I also want to be able to compare X and Y values with fixed values..

For instance I want to be able to compare:

is X = 5 and Y = 2?

then be able to take control of the program loop.


Solution

  • You only assign to input once before the loop.

    You need to reassign it inside the loop to update its value.

    Point p1 = new Point(5, 2);
    ConsoleKeyInfo input = Console.ReadKey();
    while (input.Key != ConsoleKey.Escape)
    {
        if (input.Key == ConsoleKey.UpArrow)
        {
            p1.Y++;
            Console.WriteLine(p1.Y);
        } 
        else if (input.Key == ConsoleKey.DownArrow)
        {
            p1.Y--;
            Console.WriteLine(p1.Y);
        } 
        else if (input.Key == ConsoleKey.LeftArrow)
        {
            p1.X--;
            Console.WriteLine(p1.X);
        } 
        else if (input.Key == ConsoleKey.RightArrow)
        {
            p1.X++;
            Console.WriteLine(p1.X);
        }
        input = Console.ReadKey();
    }
    

    Disclaimer: I only fixed the current problem. I am aware, there is room for further refactoring here.


    To the initial problem:

    ConsoleKeyInfo input = Console.ReadKey();
    while (Console.ReadKey().Key != ConsoleKey.Escape)
    

    In the original code, you assign to input once and in the loop condition you take another reading, but you do not update input with that. The result is that inside the loop, you always evaluate the initial value assigned to input, never changing it to the latest reading from Console.ReadKey().


    After Edit:

    You can add further checks like this:

    Point p1 = new Point(5, 2);
    ConsoleKeyInfo input = Console.ReadKey();
    while (input.Key != ConsoleKey.Escape)
    {
        if (input.Key == ConsoleKey.UpArrow)
        {
            p1.Y++;
            Console.WriteLine(p1.Y);
        } 
        else if (input.Key == ConsoleKey.DownArrow)
        {
            p1.Y--;
            Console.WriteLine(p1.Y);
        } 
        else if (input.Key == ConsoleKey.LeftArrow)
        {
            p1.X--;
            Console.WriteLine(p1.X);
        } 
        else if (input.Key == ConsoleKey.RightArrow)
        {
            p1.X++;
            Console.WriteLine(p1.X);
        }
    
        if ( p1.X == 5 && p1.Y == 2 )
        {
            Console.WriteLine("You hit the mark!");
            break; // exit loop now.
        }
    
        input = Console.ReadKey();
    }