0

I have the following code, which waits for user input via arrow keys to move, or escape to end the program.

Console.WriteLine(startNode.Render(true));
LevelState currentNode = startNode;
while (Console.ReadKey(true).Key != ConsoleKey.Escape)
{
    if (Console.ReadKey(true).Key == ConsoleKey.UpArrow)
    {
        Console.WriteLine("up");
        LevelState move = currentNode.StepInDirection(CardinalDirection.Up);
        if (move != null)
        {
            currentNode = move;
            Console.WriteLine(currentNode.Render(true));
        }
    }
    //ditto for the other 3 directions
}

However, it only occasionally acknowledges my input. If I quickly tap the escape key, for example, most of the time nothing happens. So the Console.ReadKey method seems extremely unreliable to me. What is a better alternative?

NounVerber
  • 135
  • 7
  • Your read key pattern seems wrong – TheGeneral Jan 13 '19 at 02:17
  • You keep reading keys inside your loop, that is your problem. In the worst case, you would need to press ESC as many times as you have `if (Console.ReadKey(true).Key == ...` lines inside your loop. (Basically, for every Console.ReadKey(true) occuring in your loop you would need to press a key again before getting back to your ESC-key check...) –  Jan 13 '19 at 02:17
  • 2
    Instead of reading keys multiple times within the loop, read a key only once per loop iteration and assign it to a variable. Then check if the value of this variable is the ESC key, or other keys. –  Jan 13 '19 at 02:18
  • Take a look at `Console.KeyAvailable`: https://learn.microsoft.com/en-us/dotnet/api/system.console.keyavailable?view=netframework-4.7.2 – mrmowji Jan 13 '19 at 02:21

1 Answers1

1

You are calling ReadKey too many times

This is a better pattern

ConsoleKey key;
while ((key = Console.ReadKey(true).Key) != ConsoleKey.Escape)
{
   if (key == ConsoleKey.UpArrow)
   {
      ///
   }
   //ditto for the other 3 directions

}

or

// read key once
ConsoleKey key = Console.ReadKey(true).Key;
while (key != ConsoleKey.Escape)
{
   if (key == ConsoleKey.UpArrow)
   {
      ///
   }

   //ditto for the other 3 directions
   key = Console.ReadKey(true).Key;
}
TheGeneral
  • 79,002
  • 9
  • 103
  • 141