//this method moves the hazards
 static void MoveTheHazards(GameObject hazard)
 {
     hazard.y++;
 }
        static void Main()
        {
            #region Setting up the scene
            //before anything else, change the console window
            Console.BufferWidth = Console.WindowWidth = 50;
            Console.BufferHeight = Console.WindowHeight = 39;

            int gameSpeedDelay = 250;
            int livesNum = 10;
            int scoreNum = 0;
            int levelNum = 0;

            //create a list of gameobjects to hold the game hazards in runtime
            List<GameObject> theHazardsList = new List<GameObject>();
            #endregion

            #region Create the player
            //create the player object
            GameObject playerLeft = new GameObject();
            playerLeft.x = (Console.WindowWidth / 2) - 1;
            playerLeft.y = Console.WindowHeight - 1;
            playerLeft.symbol = "(";
            playerLeft.color = ConsoleColor.White;

            GameObject playerMid = new GameObject();
            playerMid.x = playerLeft.x + 1;
            playerMid.y = Console.WindowHeight - 1;
            playerMid.symbol = "O";
            playerMid.color = ConsoleColor.White;

            GameObject playerRight = new GameObject();
            playerRight.x = playerMid.x + 1;
            playerRight.y = Console.WindowHeight - 1;
            playerRight.symbol = ")";
            playerRight.color = ConsoleColor.White;
            #endregion

            //keep the game running until the player loses all their lives
            while (livesNum > 0)
            {
                //initialise the collision boolean
                bool contact = false;

                #region Create the hazards
                //creating the game hazards
                string[] theHazardsStr = { "+", "%", "$", "#", "!", "^", "@", "*", "&", ".", ";" };
                ConsoleColor[] rocksColor = { ConsoleColor.White, ConsoleColor.Green, ConsoleColor.Yellow, ConsoleColor.Red, ConsoleColor.Cyan, ConsoleColor.Magenta };

                //choose the type and details of the hazards
                Random chooseXPos = new Random();
                Random chooseHazard = new Random();
                Random chooseDensity = new Random();
                Random chooseHazardColour = new Random();

                //random density in the range
                int hazardDensity = chooseDensity.Next(0, 3);

                for (int i = 0; i < hazardDensity; i++)
                {
                    GameObject hazard = new GameObject();
                    hazard.x = chooseXPos.Next(1, (Console.WindowWidth - 1));
                    hazard.y = 0;

                    //ensure different colours
                    for (int k = 0; k <= 1; k++)
                    {
                        hazard.color = rocksColor[chooseHazardColour.Next(0, rocksColor.Length)];
                    }

                    //ensure different hazards
                    for (int j = 0; j <= 1; j++)
                    {
                        hazard.symbol = theHazardsStr[chooseHazard.Next(0, theHazardsStr.Length)];
                    }

                    theHazardsList.Add(hazard);
                }
                #endregion

                #region Draw and move the hazards
                //draw the hazards gameobjects via the PlaceAtThisPos method (loop through the List to create a stream of hazards)
                foreach (var hazard in theHazardsList)
                {
                      if(hazard.y < Console.WindowHeight - 1)
                      {
                            PlaceAtThisPos(hazard.x, hazard.y, hazard.symbol, hazard.color);
                      }
                }

                //hazard movement logic
                foreach (var hazard in theHazardsList)
                {
                    MoveTheHazards(hazard);
                }

                //diminish the number of hazards
                if (theHazardsList.Count > 250)
                {
                    for (int i = 0; i < 17; i++)
                    {
                        theHazardsList.RemoveAt(0);
                    }
                }
                #endregion

                #region Draw the player
                //draw the player gameobject via the PlaceAtThisPos method (invoke for each body part)
                PlaceAtThisPos(playerLeft.x, playerLeft.y, playerLeft.symbol, playerLeft.color);
                PlaceAtThisPos(playerMid.x, playerMid.y, playerMid.symbol, playerMid.color);
                PlaceAtThisPos(playerRight.x, playerRight.y, playerRight.symbol, playerRight.color);
                #endregion

                #region Player movement

                //player movement logic - check the key being pressed and adjust the player gameobject position accordingly
                while (Console.KeyAvailable)
                {
                    ConsoleKeyInfo theUsedKey = Console.ReadKey();
                    if (theUsedKey.Key == ConsoleKey.LeftArrow)
                    {
                        if (playerLeft.x >= 1)
                        {
                            playerLeft.x = playerLeft.x - 1;
                            playerMid.x = playerMid.x - 1;
                            playerRight.x = playerRight.x - 1;
                        }
                    }

                    else if (theUsedKey.Key == ConsoleKey.RightArrow)
                    {
                        if (playerRight.x < Console.WindowWidth - 1)
                        {
                            playerLeft.x = playerLeft.x + 1;
                            playerMid.x = playerMid.x + 1;
                            playerRight.x = playerRight.x + 1;
                        }
                    }

                }//end of loop

                #endregion

                #region Collision and game control.

                contact = false;
                //check if the player gameobject has collided with any hazards
                for (int i = 0; i < theHazardsList.Count; i++)
                {
                    if (
                        playerLeft.x == theHazardsList[i].x ||
                        playerMid.x == theHazardsList[i].x ||
                        playerRight.x == theHazardsList[i].x &&
                        playerMid.y == theHazardsList[i].y
                       )
                        {
                         contact = true;
                        }
                } //end of loop

                //consequences, if the hazards hit the player
                if (contact == true)
                {
                    Console.Beep();

                    PlaceAtThisPos(playerLeft.x, playerLeft.y, "-", ConsoleColor.Red);
                    PlaceAtThisPos(playerMid.x, playerMid.y, "^", ConsoleColor.Red);
                    PlaceAtThisPos(playerRight.x, playerRight.y, "-", ConsoleColor.Red);

                    //livesNum--;
                }

                contact = false;

                scoreNum++;

                Thread.Sleep(gameSpeedDelay);

                Console.Clear();

                //increase the level and the game speed/difficulty
                if (scoreNum % 100 == 0)
                {
                    gameSpeedDelay -= 5;
                    levelNum++;
                }
                #endregion
            } //end of loop, i.e., GAME OVER

            #region Game Over
            //GAME OVER messages
            Console.Clear();

            Console.WriteLine();
            Console.WriteLine(" GAME OVER!");
            Console.WriteLine();

            Console.WriteLine(" You achieved a score of {0} and reached level {1}. Better luck next time!", scoreNum, levelNum);
            Console.WriteLine(" Press [Enter] to close the game.");

            Console.ReadLine();
            Environment.Exit(0);
            #endregion
        }