I have implemented the Falling rocks game in C#. The instructions are simple: Don't get hit by rocks. The game is running quite well, however there are some bugs that occur and furthermore, I would like to receive advice whether I could make the code less complicated if possible.using System;using System.Collections;using System.Collections.Generic;using System.Linq;using System.Threading;// a structure to make life easierstruct Object{    public int x;    public int y;    public char ch;    public ConsoleColor color;}class Program{    // in order to print characters on certain positions    static void PrintOnPosition(int col, int row, char ch,        ConsoleColor color = ConsoleColor.Gray)    {        Console.SetCursorPosition(col, row);        Console.ForegroundColor = color;        Console.Write(ch);    }    // in order to print strings on certain positions    static void PrintStringOnPosition(int col, int row, string str,        ConsoleColor color = ConsoleColor.Gray)    {        Console.SetCursorPosition(col, row);        Console.ForegroundColor = color;        Console.Write(str);    }    static void Main()    {        // Some properties and variables to be used        Console.CursorVisible = false;        Console.BufferHeight = Console.WindowHeight = 18;        Console.WindowWidth = 20;        Console.BufferWidth = 20;        Random randomGenerator = new Random();        double sleeptime = 200;        double score = 0;        int lives = 5;        // constructing the dwarf elements (O)        Object DwarfLeft = new Object();        DwarfLeft.x = 9;        DwarfLeft.y = Console.WindowHeight - 1;        DwarfLeft.ch = '(';        DwarfLeft.color = ConsoleColor.Gray;        Object DwarfCenter = new Object();        DwarfCenter.x = 10;        DwarfCenter.y = Console.WindowHeight - 1;        DwarfCenter.ch = 'O';        DwarfCenter.color = ConsoleColor.Gray;        Object DwarfRight = new Object();        DwarfRight.x = 11;        DwarfRight.y = Console.WindowHeight - 1;        DwarfRight.ch = ')';        DwarfRight.color = ConsoleColor.Gray;        List<Object> Rocks = new List<Object>();        // Writing the instructions at the start of the game        PrintStringOnPosition(0, 5,  The aim of the game is to avoid all the rocks. Good luck!, ConsoleColor.Yellow);        PrintStringOnPosition(0, 9, Pick, ConsoleColor.Yellow);        PrintOnPosition(5, 9, (char)3, ConsoleColor.Red);        PrintStringOnPosition(7, 9, for lives, ConsoleColor.Yellow);        PrintStringOnPosition(0, 10, Pick, ConsoleColor.Yellow);        PrintOnPosition(5, 10, '$', ConsoleColor.Green);        PrintStringOnPosition(7, 10, for money, ConsoleColor.Yellow);        PrintStringOnPosition(5, 13, Good luck!, ConsoleColor.Red);        PrintOnPosition(17, 0, ' ', ConsoleColor.Black);        Console.ReadLine();        Console.Clear();        // making the lines of play        for (int i = 0; i <= Console.WindowWidth - 1; i++)        {            PrintOnPosition(i, 4, '_', ConsoleColor.White);        }        while (true)        {            // The bool values in case we get hit. They are different for the parts of the dwarf elements            bool hit = false;            bool hitleft = false;            bool hitcenter = false;            bool hitright = false;            // the chance is for making bonuses from time to time            int chance = randomGenerator.Next(0, 100);            {                Object NewRock = new Object();                NewRock.x = randomGenerator.Next(0, 19);                NewRock.y = 5;                if (chance < 1)                {                    // It's a heart character                    NewRock.ch = (char)3;                    NewRock.color = ConsoleColor.Red;                }                else if (chance < 10)                {                    NewRock.ch = '$';                    NewRock.color = ConsoleColor.Green;                }                else if (chance < 100)                {                    NewRock.ch = '@';                    NewRock.color = ConsoleColor.Cyan;                }                Rocks.Add(NewRock);            }            //moving the dwarf            if (Console.KeyAvailable)            {                ConsoleKeyInfo userInput = Console.ReadKey();                // In order to avoid the moving bug (If numerous keys are pressed, the program will execute each one)                while (Console.KeyAvailable)                {                    Console.ReadKey(true);                }                if (userInput.Key == ConsoleKey.LeftArrow && DwarfLeft.x > 0)                {                    PrintOnPosition(DwarfLeft.x, DwarfLeft.y, ' ', DwarfLeft.color);                    PrintOnPosition(DwarfCenter.x, DwarfCenter.y, ' ', DwarfCenter.color);                    PrintOnPosition(DwarfRight.x, DwarfRight.y, ' ', DwarfRight.color);                    DwarfLeft.x = DwarfLeft.x - 1;                    DwarfCenter.x = DwarfCenter.x - 1;                    DwarfRight.x = DwarfRight.x - 1;                }                if (userInput.Key == ConsoleKey.RightArrow && DwarfRight.x < Console.WindowWidth - 1)                {                    PrintOnPosition(DwarfLeft.x, DwarfLeft.y, ' ', DwarfLeft.color);                    PrintOnPosition(DwarfCenter.x, DwarfCenter.y, ' ', DwarfCenter.color);                    PrintOnPosition(DwarfRight.x, DwarfRight.y, ' ', DwarfRight.color);                    DwarfLeft.x = DwarfLeft.x + 1;                    DwarfCenter.x = DwarfCenter.x + 1;                    DwarfRight.x = DwarfRight.x + 1;                }            }            PrintOnPosition(DwarfLeft.x, DwarfLeft.y, DwarfLeft.ch, DwarfLeft.color);            PrintOnPosition(DwarfCenter.x, DwarfCenter.y, DwarfCenter.ch, DwarfCenter.color);            PrintOnPosition(DwarfRight.x, DwarfRight.y, DwarfRight.ch, DwarfRight.color);            // The new list is made in order to add the next position of the rock which is y + 1. Thus making it fall            List<Object> newList = new List<Object>();            for (int i = 0; i < Rocks.Count; i++)            {                Object oldRock = Rocks[i];                Object newObject = new Object();                newObject.x = oldRock.x;                newObject.y = oldRock.y + 1;                newObject.ch = oldRock.ch;                newObject.color = oldRock.color;                // check if we get hit                if ((newObject.x == DwarfLeft.x && newObject.y == DwarfLeft.y && newObject.ch == '@'))                {                    hit = true;                    hitleft = true;                }                else if ((newObject.x == DwarfCenter.x && newObject.y == DwarfCenter.y && newObject.ch == '@'))                {                    hit = true;                    hitcenter = true;                }                else if (newObject.x == DwarfRight.x && newObject.y == DwarfRight.y && newObject.ch == '@')                {                    hit = true;                    hitright = true;                }                    // money                else if (newObject.x == DwarfLeft.x && newObject.y == DwarfLeft.y && newObject.ch == '$')                {                    score += 500;                }                else if (newObject.x == DwarfCenter.x && newObject.y == DwarfCenter.y && newObject.ch == '$')                {                    score += 500;                }                else if (newObject.x == DwarfRight.x && newObject.y == DwarfRight.y && newObject.ch == '$')                {                    score += 500;                }                // lives                else if (newObject.x == DwarfLeft.x && newObject.y == DwarfLeft.y && newObject.ch == (char)3)                {                    lives += 1;                }                else if (newObject.x == DwarfCenter.x && newObject.y == DwarfCenter.y && newObject.ch == (char)3)                {                    lives += 1;                }                else if (newObject.x == DwarfRight.x && newObject.y == DwarfRight.y && newObject.ch == (char)3)                {                    lives += 1;                }                // Add the new object in the newList until it reaches the end of the screen                if (newObject.y < Console.WindowHeight)                {                    newList.Add(newObject);                }            }            // consequences for being hit            if (hit == true)            {                // checks if you have 1 live left. Else the game will continue until you reach -1 lives                if (lives < 2)                {                    PrintStringOnPosition(0, 0, GAME OVER!, ConsoleColor.Red);                    // We print the X in order to see the place of casualty                    if (hitleft == true)                    {                        PrintOnPosition(DwarfLeft.x, DwarfLeft.y, 'X', ConsoleColor.Red);                    }                    else if (hitcenter == true)                    {                        PrintOnPosition(DwarfCenter.x, DwarfCenter.y, 'X', ConsoleColor.Red);                    }                    else if (hitright == true)                    {                        PrintOnPosition(DwarfRight.x, DwarfRight.y, 'X', ConsoleColor.Red);                    }                    PrintOnPosition(17, 0, ' ', ConsoleColor.Black);                    Console.ReadLine();                    PrintStringOnPosition(0, 0, @           , ConsoleColor.Red);                    return;                }                // Print an X on the hit position                if (hitleft == true)                {                    PrintOnPosition(DwarfLeft.x, DwarfLeft.y, 'X', ConsoleColor.Red);                }                else if (hitcenter == true)                {                    PrintOnPosition(DwarfCenter.x, DwarfCenter.y, 'X', ConsoleColor.Red);                }                else if (hitright == true)                {                    PrintOnPosition(DwarfRight.x, DwarfRight.y, 'X', ConsoleColor.Red);                }                // If we still have lives, the game continues                PrintStringOnPosition(0, 0, Press enter, ConsoleColor.Red);                // this is made in order to avoid a bug in which when you press some letter, it prints it on the console                // on the last position the cursor was                PrintOnPosition(17, 0, ' ', ConsoleColor.Black);                Console.ReadLine();                // Clear the positions of the old objects                PrintStringOnPosition(0, 0, @           , ConsoleColor.Red);                foreach (Object rock in Rocks)                {                    PrintOnPosition(rock.x, rock.y, ' ', ConsoleColor.Black);                }                Rocks.Clear();                newList.Clear();                // Consequences                lives--;                sleeptime += 20;            }            // This basically makes the rocks move. The idea is - Clear the old rocks and make the new ones            foreach (Object rock in Rocks)            {                PrintOnPosition(rock.x, rock.y, ' ', ConsoleColor.Black);            }            // The object Rocks takes the value of the new list which contains the positions of the new rocks            Rocks = newList;            foreach (Object rock in Rocks)            {                PrintOnPosition(rock.x, rock.y, rock.ch, rock.color);            }            // The score and lives            PrintStringOnPosition(7, 2, Score:  + (int)score, ConsoleColor.Cyan);            PrintStringOnPosition(7, 3, Lives:  + lives, ConsoleColor.Yellow);            // Making the score increase and the speed of the game increase constantly            score += 14.66;            sleeptime -= 0.5;            if (sleeptime < 100)            {                sleeptime = 100;            }            if (sleeptime > 200)            {                sleeptime = 200;            }            // Set the speed of the program            Thread.Sleep((int)sleeptime);        }    }}The problem is that the speed of the dwarf is the same as the game speed. How can I make it constant throughout the game? Furthermore, if the position of the dwarf reaches the end of the window to the right, it bounces up as well as the buffer.
Falling Rocks Game
c#;game;console
A few things that should help.  Instead of using a keyword Object for your custom object using a more descriptive name like GameObject makes it more obvious what the object's purpose is.Since there is a difference between the rocks and the dwarf but they have properties in common, making the main object a class and having 2 derived classes(Dwarf, Rock) makes the division between them more obvious.Using col, row instead of x y fits better with your PrintOnPosition method.Since PrintOnPosition and PrintStringOnPosition are basically the same methods with slightly different parameters having PrintOnPosition overloaded to take char or string makes sense here.  to make it more obvvious I changed their name to chartoprint and stringtoprint.Since the main difference between the rocks and the dwarf is the shape.  A rock is a single character and a dwarf is a 3 character string.  By removing that property from GameObject and putting it in the derived classes you only need one object to represent the dwarf and since PrintOnPosition is overloaded the syntax stays the same.Using all those booleans to represent a hit seems kind of awkward.  An enum,HitPosition with qualified names(None,HitLeft,HitCenter,HitRight) simplifies the way your hits work.  Instead of checking for true just check if it equals None, then use an algorithm to determine which position was hit.An enum would also work well for the different rock shapes(Heart,Money,Rock).  This makes the code easier to understand instead of magic characters.I went through your code and made some changes.  There are probably other areas that could be improved, but this should give you a good start.  I think I covered all of my changes, but just in case here is the modified code.  I didn't get a chance yet to look at the bug:using System;using System.Collections;using System.Collections.Generic;using System.Linq;using System.Threading;namespace FallingRocks{    // a structure to make life easier    class GameObject    {        public int col;        public int row;        public ConsoleColor color;    }    class Dwarf : GameObject    {        public readonly string shape = (0);    }    class Rock : GameObject    {        public char shape;    }    enum HitPosition    {        None = 0,        HitLeft = 1,        HitCenter = 2,        HitRight = 3    }    enum RockShape    {        Rock = '@',        Heart = 3,        Money = '$'    }    class Program    {        static readonly string[] hitshapes = new string[] { , X0), (X), (0X };        // in order to print characters on certain positions        static void PrintOnPosition(int col, int row, char chartoprint,            ConsoleColor color = ConsoleColor.Gray)        {            Console.SetCursorPosition(col, row);            Console.ForegroundColor = color;            Console.Write(chartoprint);        }        // in order to print strings on certain positions        static void PrintOnPosition(int col, int row, string stringtoprint,            ConsoleColor color = ConsoleColor.Gray)        {            Console.SetCursorPosition(col, row);            Console.ForegroundColor = color;            Console.Write(stringtoprint);        }        static void Main()        {            // Some properties and variables to be used            Console.CursorVisible = false;            Console.BufferHeight = Console.WindowHeight = 18;            Console.WindowWidth = 20;            Console.BufferWidth = 20;            Random randomGenerator = new Random();            double sleeptime = 200;            double score = 0;            int lives = 5;            // constructing the dwarf elements (O)            Dwarf newDwarf = new Dwarf();            newDwarf.col = 9;            newDwarf.row = Console.WindowHeight - 1;            newDwarf.color = ConsoleColor.Gray;            List<Rock> Rocks = new List<Rock>();            // Writing the instructions at the start of the game            PrintOnPosition(0, 5,  The aim of the game is to avoid all the rocks. Good luck!, ConsoleColor.Yellow);            PrintOnPosition(0, 9, Pick, ConsoleColor.Yellow);            PrintOnPosition(5, 9, (char)3, ConsoleColor.Red);            PrintOnPosition(7, 9, for lives, ConsoleColor.Yellow);            PrintOnPosition(0, 10, Pick, ConsoleColor.Yellow);            PrintOnPosition(5, 10, '$', ConsoleColor.Green);            PrintOnPosition(7, 10, for money, ConsoleColor.Yellow);            PrintOnPosition(5, 13, Good luck!, ConsoleColor.Red);            PrintOnPosition(17, 0, ' ', ConsoleColor.Black);            Console.ReadLine();            Console.Clear();            // making the lines of play            for(int i = 0; i <= Console.WindowWidth - 1; i++)            {                PrintOnPosition(i, 4, '_', ConsoleColor.White);            }            while(true)            {                // The bool values in case we get hit. They are different for the parts of the dwarf elements                HitPosition newHitPosition = HitPosition.None;                // the chance is for making bonuses from time to time                int chance = randomGenerator.Next(0, 100);                {                    Rock newRock = new Rock();                    newRock.col = randomGenerator.Next(0, 19);                    newRock.row = 5;                    if(chance < 1)                    {                        // It's a heart character                        newRock.shape = (char)RockShape.Heart;                        newRock.color = ConsoleColor.Red;                    }                    else if(chance < 10)                    {                        newRock.shape = (char)RockShape.Money;                        newRock.color = ConsoleColor.Green;                    }                    else if(chance < 100)                    {                        newRock.shape = (char)RockShape.Rock;                        newRock.color = ConsoleColor.Cyan;                    }                    Rocks.Add(newRock);                }                //moving the dwarf                if(Console.KeyAvailable)                {                    ConsoleKeyInfo userInput = Console.ReadKey();                    // In order to avoid the moving bug (If numerous keys are pressed, the program will execute each one)                    while(Console.KeyAvailable)                    {                        Console.ReadKey(true);                    }                    if(userInput.Key == ConsoleKey.LeftArrow && newDwarf.col > 0)                    {                        PrintOnPosition(newDwarf.col--, newDwarf.row,    , newDwarf.color);                    }                    if(userInput.Key == ConsoleKey.RightArrow && newDwarf.col < Console.WindowWidth - 2)                    {                        PrintOnPosition(newDwarf.col++, newDwarf.row,    , newDwarf.color);                    }                }                PrintOnPosition(newDwarf.col, newDwarf.row, newDwarf.shape, newDwarf.color);                // The new list is made in order to add the next position of the rock which is y + 1. Thus making it fall                List<Rock> newList = new List<Rock>();                for(int i = 0; i < Rocks.Count; i++)                {                    Rock oldRock = Rocks[i];                    Rock newRock = new Rock();                    newRock.col = oldRock.col;                    newRock.row = oldRock.row + 1;                    newRock.shape = oldRock.shape;                    newRock.color = oldRock.color;                    // check if we get hit                    if((newRock.col == newDwarf.col || newRock.col == newDwarf.col + 1 || newRock.col == newDwarf.col + 2) && newRock.row == newDwarf.row)                    {                        switch(newRock.shape)                        {                            case '@':                                newHitPosition = (HitPosition)Enum.Parse(typeof(HitPosition), ((newRock.col - newDwarf.col) + 1).ToString());                                break;                            case '$':                                score += 500;                                break;                            case (char)3:                                lives += 1;                                break;                        }                    }                    // Add the new object in the newList until it reaches the end of the screen                    if(newRock.row < Console.WindowHeight)                    {                        newList.Add(newRock);                    }                }                // consequences for being hit                if(newHitPosition != HitPosition.None)                {                    PrintOnPosition(newDwarf.col, newDwarf.row, hitshapes[(int)newHitPosition], ConsoleColor.Red);                    // checks if you have 1 live left. Else the game will continue until you reach -1 lives                    if(lives < 2)                    {                        PrintOnPosition(0, 0, GAME OVER!, ConsoleColor.Red);                        // We print the X in order to see the place of casualty                                               PrintOnPosition(17, 0, ' ', ConsoleColor.Black);                        Console.ReadLine();                        PrintOnPosition(0, 0, @           , ConsoleColor.Red);                        return;                    }                    // If we still have lives, the game continues                    PrintOnPosition(0, 0, Press enter, ConsoleColor.Red);                    // this is made in order to avoid a bug in which when you press some letter, it prints it on the console                    // on the last position the cursor was                    PrintOnPosition(17, 0, ' ', ConsoleColor.Black);                    Console.ReadLine();                    // Clear the positions of the old objects                    PrintOnPosition(0, 0, @           , ConsoleColor.Red);                    foreach(Rock rock in Rocks)                    {                        PrintOnPosition(rock.col, rock.row, ' ', ConsoleColor.Black);                    }                    Rocks.Clear();                    newList.Clear();                    // Consequences                    lives--;                    sleeptime += 20;                }                // This basically makes the rocks move. The idea is - Clear the old rocks and make the new ones                foreach(Rock rock in Rocks)                {                    PrintOnPosition(rock.col, rock.row, ' ', ConsoleColor.Black);                }                // The object Rocks takes the value of the new list which contains the positions of the new rocks                Rocks = newList;                foreach(Rock rock in Rocks)                {                    PrintOnPosition(rock.col, rock.row, rock.shape, rock.color);                }                // The score and lives                PrintOnPosition(7, 2, Score:  + (int)score, ConsoleColor.Cyan);                PrintOnPosition(7, 3, Lives:  + lives, ConsoleColor.Yellow);                // Making the score increase and the speed of the game increase constantly                score += 14.66;                sleeptime -= 0.5;                if(sleeptime < 100)                {                    sleeptime = 100;                }                if(sleeptime > 200)                {                    sleeptime = 200;                }                // Set the speed of the program                Thread.Sleep((int)sleeptime);            }        }    }}