1

This code shows result like:

distance from target : 10
distance from target : 9
distance from target : 8
(line by line)

I want to show the result like- distance from target : 10, then 9,8,7 replacing the place of 10, (only the place of 10 will update)

public void Attack()
{
    for (int i = 1; i < 3; i++)
    {
        if (i == 1)
        {
            Console.WriteLine("Target Locked (+)");
            Thread.Sleep(2000);
        }
        if (i == 2)
        {
            Console.WriteLine("Fired!");
            Thread.Sleep(1000);
        }
    }
    Random random = new Random();
    int distance = random.Next(100, 3000);
    for (int i = distance; i > 0; i = i - 3)
    {
        Console.WriteLine("distance from target : " + i);
        Thread.Sleep(30);
        //Console.Clear();
    }
    Console.WriteLine("BloooW!");
}
tanzim abir
  • 17
  • 1
  • 4
  • Look at these properties in the console class: CursotTop, CursorLeft and this method SetCursorPosition – Steve Dec 26 '19 at 18:16
  • If I understand you correct.. try Console.Write() instead of Console.WriteLine() – G.Y Dec 26 '19 at 18:17
  • @G.Y I think he wants his output to change from `10` to `9`, etc, rather than `10, 9, 8, 7,...` –  Dec 26 '19 at 18:23
  • Also, if you know total count you can pad the number to the width of the biggest number. If appropriate. Then the width of text line stays the same all way through. – Andrew Truckle Dec 26 '19 at 18:30

4 Answers4

3

You could use CursorTop, CursorLeft and SetCursorPosition to fine control the point where you write your output. But the real trick is to delete what you have previously written in that place. Here you could use the format string capabilities of Console.Write/WriteLine

    // This needs to be written just one time
    Console.Write("distance from target : ");
    // Now get the current cursor position after the write above
    int posX = Console.CursorLeft;
    int posY = Console.CursorTop;


    for (int i = distance; i > 0; i = i - 3)
    {
        // Position the cursor where needed
        Console.SetCursorPosition(posX, posY);

        // Replace the previous write with a number aligned on the left on 4 spaces
        Console.Write($"{i,-4:D}");
        // As an alternative to SetCursorPosition you could have
        // Console.CursorLeft -= 4;
        // but, to me this is less clear....

        Thread.Sleep(30);
    }
    // Do not forget to jump to the next line
    Console.WriteLine("\r\nBloooW!");
Steve
  • 213,761
  • 22
  • 232
  • 286
  • Thanks, its tricky and nice. but i think there should be some better ways to solve this. – tanzim abir Dec 26 '19 at 21:16
  • 1
    I don't know if there is a better way. Perhaps something like replacing the Console class with your own, or taking control of input/output streams used by the console. Not sure if they worth the time to investigate further. Actually this is how the standard console works. Every time you write the x,y pos change to reflect the new output point. And if you want to change that point you have the entry point to do it with CursorTop and CursorLeft – Steve Dec 26 '19 at 21:25
2

You can change from Console.WriteLine to Console.Write add a \r to the front of your string:

        for (int i = distance; i > 0; i = i - 3)
        {
            Console.Write("\rdistance from target : " + i);
            Thread.Sleep(30);
            //Console.Clear();
        }
        Console.WriteLine("");

This will cause the console to return to the beginning of the line and write the string again covering the string that was there from the last write. Also be sure to add a Console.WriteLine(""); after the for loop to move to the next line, so your next write doesn't end up starting on that line.

This solution works best if your string will only get longer.

If your string is is going to get shorter you can add some white space to end of the string like this:

 Console.Write("\rdistance from target : {0} ", i);

This is the case for you when you go form 10 to 9

Nifim
  • 4,758
  • 2
  • 12
  • 31
1

then you should first delete the distance written to console, it can be done with one or more backspaces \b

change

for (int i = distance; i > 0; i = i - 3)
            {
                Console.WriteLine("distance from target : " + i);
                Thread.Sleep(30);
                //Console.Clear();
            }

to

int lastDistanceLength = 0; // save the last number of distance chars written

for (int i = distance; i > 0; i = i - 3)
{
   if(lastDistanceLength == 0) { // no distance chars written yet.
       Console.Write("distance from target : " + i);
    } 
    else  { 
       for(int j=0;j‹lastDistanceLength;j++)
          Console.Write("\b"); // delete old distance
       Console.Write(""+i);

    }
    lastDistanceLength = i==10 ? 2 : 1;           
    Thread.Sleep(30);
    //Console.Clear();
}
Console.WriteLine("\r\nBloooW!");

you will most likely need a more advanced algorithm for calculating lastDistanceLength, maybe just convert i to a string and take the length e.g. lastDistanceLength = (""+i).Length

there is a quite comprehensive explanation here : Is there a way to delete a character that has just been written using Console.WriteLine?

MikNiller
  • 1,242
  • 11
  • 17
0

You can use Console.CursorTop like this :

for (int i = distance; i > 0; i = i - 3)
{
    Console.WriteLine("distance from target : " + i + "    "); // dirty trick to erase longer previous numbers
    Thread.Sleep(30);
    Console.CursorTop--;
}
Console.CursorTop++; // so that we advance to the next line after the loop.

It moves cursor one line up, so subsequent calls overwrite what was previously in line above.

This approach is not the most efficient one as it will rewrite whole line, but it is simple and from user's point of view only numeric value will be updated.

If so small performance differences matter, you can try to set cursor position more precisely to the place where numeric value starts. I am not sure it is possible but worth trying if it matters.

GrayCat
  • 1,749
  • 3
  • 19
  • 30