private static SnakeOrLadderEntity ParseLine(string line)
        {
            if (line.StartsWith("#"))
            {
                //Ignorring lines starting with #, those can be used for comments
                return(null);
            }

            if (string.IsNullOrWhiteSpace(line))
            {
                //Ignorring empty lines
                return(null);
            }

            string[] lineParts = line.Split(' ');

            if (lineParts.Length < 2)
            {
                Console.WriteLine($"ERROR: Head or tail position is missing in line. Line content: {line}");
                return(null);
            }

            if (lineParts.Length > 2)
            {
                Console.WriteLine($"WARNING: Line contents additional data: {line}. Additional data in the line will be ignored.");
            }

            int headPosition;
            int tailPosition;

            try
            {
                headPosition = int.Parse(lineParts[0]);
                tailPosition = int.Parse(lineParts[1]);
            }
            catch
            {
                Console.WriteLine($"ERROR: Components of a line can't be parsed to int. Line content: {line}");
                return(null);
            }

            if (!SnakeOrLadderValidator.Validate(headPosition, tailPosition))
            {
                return(null);
            }

            SnakeOrLadderEntity snakeOrLadder = new SnakeOrLadderEntity(headPosition, tailPosition);

            return(snakeOrLadder);
        }
        private static SnakeOrLadderEntity[] ParseLines(string[] lines)
        {
            List <SnakeOrLadderEntity> snakesAndLaddersOnBoard = new List <SnakeOrLadderEntity>();

            foreach (string line in lines)
            {
                SnakeOrLadderEntity snakeOrLadder = ParseLine(line);

                if (snakeOrLadder != null)
                {
                    Console.WriteLine($"Loadded a {snakeOrLadder.GetVariant()} from {snakeOrLadder.HeadPosition} to {snakeOrLadder.TailPosition}.");
                    snakesAndLaddersOnBoard.Add(snakeOrLadder);
                }
            }

            if (!SnakeOrLadderValidator.ValidateSnakesLadderCombinations(snakesAndLaddersOnBoard))
            {
                return(new SnakeOrLadderEntity[0]);
            }

            return(snakesAndLaddersOnBoard.ToArray());
        }
        public OneGameStatisticsDto Simlulate(int maxTurns, bool liveGameLogging = false)
        {
            //player starts out of the game board
            int playerPosition = 0;

            int thrownDices = 0;

            int numberOfJumps = 0;
            int numberOfTimesPlayerIsBlocked = 0;

            while (true)
            {
                if (thrownDices == maxTurns)
                {
                    if (liveGameLogging)
                    {
                        Console.WriteLine($"Max turns ({maxTurns}) reached wihtout reaching the goal! Better luck in next game!");
                    }
                    break;
                }

                int diceResult = ThrowDice();
                thrownDices++;
                if (liveGameLogging)
                {
                    Console.WriteLine($"\r\nPlayer is on position {playerPosition}. Dice gave result {diceResult} on throwing number {thrownDices}.");
                }


                //check if player would be moved out of the board
                if (playerPosition + diceResult > 100)
                {
                    if (liveGameLogging)
                    {
                        Console.WriteLine($"Player can't move. \t\t\t<-- IMPORTANT");
                    }
                    numberOfTimesPlayerIsBlocked++;
                    continue;
                }

                //move player
                playerPosition += diceResult;
                if (liveGameLogging)
                {
                    Console.WriteLine($"Moved player by {diceResult} to position {playerPosition}");
                }

                //execute snake or ladder jump if there is one of those at new player's position
                SnakeOrLadderEntity snakeOrLadderAtNewPlayerPosition = SnakesAndLadders.SingleOrDefault(element => element.HeadPosition == playerPosition);
                if (snakeOrLadderAtNewPlayerPosition != null)
                {
                    int whereToJump = snakeOrLadderAtNewPlayerPosition.TailPosition;

                    if (liveGameLogging)
                    {
                        Console.WriteLine($"Player jumped to position {whereToJump}. \t\t<-- IMPORTANT");
                    }
                    playerPosition = whereToJump;
                    numberOfJumps++;
                }

                //check if player reached game end
                if (playerPosition == 100)
                {
                    if (liveGameLogging)
                    {
                        Console.WriteLine($"Player won the game in {thrownDices} turns.");
                    }
                    break;
                }
            }

            OneGameStatisticsDto stats = new OneGameStatisticsDto
            {
                Turns        = thrownDices,
                Jumps        = numberOfJumps,
                BlockedTimes = numberOfTimesPlayerIsBlocked
            };

            if (liveGameLogging)
            {
                Console.WriteLine($"\r\nLast game statistics: Turns: {thrownDices}, Jumps: {numberOfJumps}, Times player was unable to move: {numberOfTimesPlayerIsBlocked}");
            }

            return(stats);
        }