'Generate Random Speed letters for Race Game in C#

I am creating a simple task just to keep practicing. Now I created a non-interactive game. And the letter are the characters which is A, B, C. Now since I've position my 'C' to 3 it is always the first one to finish. How do you random the speed of each characters?

static void Main()
        {
           

          Runner runnerA = new Runner('A');   
            Runner runnerB = new Runner('B');
            Runner runnerC = new Runner('C');

            runnerA.Position = 1;
            runnerB.Position = 3;
            runnerC.Position = 3;

            string course = "---......------.......";

            while (true)
            {
                runnerA.Position++;
                runnerB.Position++;
                runnerC.Position++;

                if (runnerA.Position == course.Length)
                {
                }

                for (int i = 0; i < course.Length; i++)
                {
                    if (runnerA.Position == i)
                    {
                        Console.Write(runnerA.Glyph);
                    }
                    else if (runnerB.Position == i)
                    {
                        Console.Write(runnerB.Glyph);
                    }
                    else if (runnerB.Position == i) {
                        Console.Write(runnerB.Glyph);
                    }
                    else // No runners on this tile.
                    {
                        Console.Write(course[i]);
                    }
                }

                Console.Write('|');

                Console.WriteLine();

                Thread.Sleep(100);
                Console.SetCursorPosition(0, 0);


            }

            
        }
    }


Solution 1:[1]

You have two else if conditions that are the same for the runnerB position. I assume that you meant that the second of them will be runnerC. I changed this, and I changed so that the position of the runners will be random in the range of the last position to end of the course string. Each random position is different from previous positions. for many runners we may think for a more efficient solution.

static void main()
{
    Runner runnerA = new Runner('A');
    Runner runnerB = new Runner('B');
    Runner runnerC = new Runner('C');
    Random rand = new Random();

    runnerA.Position = 1;
    runnerB.Position = 2;
    runnerC.Position = 3;

    string course = "---......------.......";

    while (true)
    {

        for (int i = 0; i < course.Length; i++)
        {
            if (runnerA.Position == i)
            {
                Console.Write(runnerA.Glyph);
            }
            else if (runnerB.Position == i)
            {
                Console.Write(runnerB.Glyph);
            }
            else if (runnerC.Position == i)
            {
                Console.Write(runnerC.Glyph);
            }
            else // No runners on this tile.
            {
                Console.Write(course[i]);
            }
        }

        Random rand = new Random();
        runnerA.Position = rand.Next(runnerA.Position, course.Length);
        do
         runnerB.Position = rand.Next(runnerB.Position, course.Length);
        while (runnerB.Position == runnerA.Position);

        do
         runnerC.Position = rand.Next(runnerC.Position, course.Length);
        while (runnerC.Position == runnerA.Position || runnerC.Position 
        == runnerB.Position);    
        Console.Write('|');

        Console.WriteLine();

        Thread.Sleep(100);
        Console.SetCursorPosition(0, 0);


    }
}

Solution 2:[2]

Here is a solution which works like this:

  • Runner classes are instantiated with random positions and speeds
  • Runners have a Timer property which allows to indicate when they need to be moved according to the elapsed time
  • I made a speed factor appear depending on the terrain: 1 if "-" and 0.5 if "."
  • If two runners have the same position, only one will appear

The Main void:

internal class Program
{
    static void Main()
    {
        Random random = new Random();
        string map = "-----------............------..............-----------............|";
        int interval = 50;
        List<Runner> runners = new List<Runner>
        {
            new Runner('A', random.Next(1, 10), random.Next(1, 5) * interval),
            new Runner('B', random.Next(1, 10), random.Next(1, 5) * interval),
            new Runner('C', random.Next(1, 10), random.Next(1, 5) * interval)
        };

        while (true)
        {
            foreach (Runner runner in runners)
            {
                if (runner.Position == map.Length - 1)
                {
                    Console.SetCursorPosition(0, 1);
                    Console.WriteLine($"The winner is: {runner.Glyph} !");
                    Console.ReadKey();
                }
                double mapFactor = map[runner.Position].Equals('-') ? 1 : 0.5;
                runner.Update(interval, mapFactor);
            }

            for (int i = 0; i < map.Length; i++)
            {
                Runner matchingRunner = runners.Find(x => x.Position == i);
                Console.Write(matchingRunner != null ? matchingRunner.Glyph : map[i]);
            }

            Console.WriteLine();
            Thread.Sleep(interval);
            Console.SetCursorPosition(0, 0);
        }
    }
}

And the associated Runner class:

public class Runner
{
    public char Glyph { get; set; }
    public int Position { get; set; }
    public int Speed { get; set; }
    public int Timer { get; set; }

    public Runner(char glyph, int position, int speed)
    {
        Glyph = glyph;
        Position = position;
        Speed = speed;
        Timer = 0;
    }

    public void Update(int interval, double mapFactor)
    {
        Timer += interval;
        if (Timer / mapFactor > Speed)
        {
            Timer = 0;
            Position++;
        }
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2