3
\$\begingroup\$

!!Code contains profanity for the purposes of point deduction!!

Scope: This quiz program is being wrote for a single use. Due to this the names and questions/answers will be set in stone within the Teams Class and the Answers class.

I have used the fisher-yates shuffle to randomise an array allowing the console to randomly assign either teams or team captains. I included a text-to-speech function just to try it out hence the option to turn it on or off (this works fine).

Issues: I have left a few comments describing issues I am having though as the code is operational I used Code Review rather than Stack Overflow. Please let me know if this belongs elsewhere and I will be more than happy to sort that out.

There are a couple of if statements for string.IsNullOrEmpty() that seem to make me have to use enter twice which I can't seem to work around (have read/tried so many posts).

Also looking for general advice on making my code neater or if I have any bad habits that should be addressed. Greatly appreciate all comments.

Program Class:

using System;
using System.Collections.Generic;
using System.Speech.Synthesis;

namespace PopQuiz
{
    class Program
    {
        static Random _random = new Random();

        static void Shuffle<T>(T[] array)
        {
            int n = array.Length;
            for (int i = 0; i < n; i++)
            {
                int r = i + (int)(_random.NextDouble() * (n - i));
                T t = array[r];
                array[r] = array[i];
                array[i] = t;
            }
        }

        private static void FlushKeyboard()
        {
            while (Console.In.Read() != -1) ;
        }

        static void Main(string[] args)
        {
            Console.ForegroundColor = ConsoleColor.Cyan;
            Console.TreatControlCAsInput = false;
            Console.Title = "Quiz";

            int[] array = { 1, 2, 3, 4, 5, 6, 7, 8 };
            Shuffle(array);

            //int space1 = 25;
            string Team1 = "";
            string Team2 = "";
            string team;
            string captains;
            string players1 = null;
            string text;
            ConsoleKeyInfo cki;
            Console.TreatControlCAsInput = true;

            text = "Welcome to the pop quiz!\nWould you like me to continue voicing this quiz?\nPress Y for Yes or any other key to continue without:";
            Console.WriteLine(text);
            SpeechSynthesizer synth = new SpeechSynthesizer();
            synth.SelectVoice("Microsoft Zira Desktop");
            //synth.Speak(text);

            cki = Console.ReadKey();
            Console.Clear();

            bool voiceYN = String.Equals(cki.Key.ToString(), "Y", StringComparison.InvariantCultureIgnoreCase);

            text = "Thank you for your selection, would you like me to assign you a team at random or just pick team captains for you?\nPress T for a random Team or C for team Captains:";
            Console.WriteLine(text);
            if (voiceYN == true)
            {
                synth.Speak(text);
            }

            incorrect:
            cki = Console.ReadKey();


            bool tResult = String.Equals(cki.Key.ToString(), "T", StringComparison.InvariantCultureIgnoreCase);
            bool cResult = String.Equals(cki.Key.ToString(), "C", StringComparison.InvariantCultureIgnoreCase);

            var thePlayers = Team.GetPlayer();
            {

                if (tResult == false)
                {
                    if (cResult == false)
                    {
                        text = "\nThat is not a valid selection, please enter either a T or a C";
                        Console.WriteLine(text);
                        if (voiceYN == true)
                        {
                            synth.Speak(text);
                        }
                        goto incorrect;
                    }
                    Console.Clear();
                    var myPlayer = thePlayers[array[7]];
                    captains = myPlayer.Name;
                    myPlayer = thePlayers[array[3]];

                    team = ("                         "+captains + myPlayer.Name);
                    captains = ($"                         Team 1:                   Team2:\n{team}");

                    text = ($"The selected team captains are:\n{captains}\n\nPress any key to continue when you are ready to proceed");
                    Console.WriteLine(text);
                    if (voiceYN == true)
                    {
                        synth.Speak(text);
                    }
                    Console.ReadKey();
                    Console.Clear();

                }
                else
                {
                    Console.Clear();
                    for (int i = 2; i < 9; i += 2)
                    {

                        var myPlayer1 = thePlayers[array[i - 2]];
                        var myPlayer2 = thePlayers[array[i - 1]];

                        players1 = (players1 + "                         " + myPlayer1.Name + myPlayer2.Name + "\n");

                    }

                    team = players1;
                    players1 = ("                         Team 1:                   Team2:\n" + players1);


                    text = ("You have chosen to have your teams randomly assigned.\nYour teams are shown below:");

                    Console.WriteLine("{0}\n\n{1}", text, players1);
                    if (voiceYN == true)
                    {
                        synth.Speak(text);
                    }

                }
            }



            text = "Now that the teams are set, it is time to decide your team names.\n\nTeam 1, what will your team name be?";
            Console.WriteLine(text);
            if (voiceYN == true)
            {
                synth.Speak(text);
            }

            Start:
            Team1 = Console.ReadLine();
        //This is the first if to give a true result initally when a false is expected but does not break the program
            if (string.IsNullOrEmpty(Team1))
            {
                goto Start;
            }

            text = ("\nWelcome to the game " + Team1 + "!\n\nTeam 2, now it's your turn.\nPlease enter your team name...");
            Console.WriteLine(text);
            if (voiceYN == true)
            {
                synth.Speak(text);
            }
            same:
            Team2 = Console.ReadLine();
        //This is the second
            if (string.IsNullOrEmpty(Team2))
            {
                goto same;
            }
            Console.Title = "Quiz";



            bool result = String.Equals(Team1, Team2, StringComparison.InvariantCultureIgnoreCase);

            if (result == true)
            {
                text = "\n\nYou can't have the same team names...\nStop being lazy and give me another one!";
                Console.WriteLine(text);
                if (voiceYN == true)
                {
                    synth.Speak(text);
                }
                goto same;
            }

            text = ("\n\nWelcome to the game " + Team2 + "!\nTeam names are set... Let's get ready to begin.");
            Console.WriteLine(text);
            if (voiceYN == true)
            {
                synth.Speak(text);
            }


            int tl = Team1.Length;
            int space2 = (25 - tl);
            string space = null;

            for (int i = 0; i <= space2; i++)
            {
                space = (space + " ");
            }

            team = ($"                         {Team1}{space}{Team2}\n{team}\n\n");
            if (voiceYN == false)
            {            
                Console.WriteLine("\n3");
                System.Threading.Thread.Sleep(1000);
                Console.WriteLine("2");
                System.Threading.Thread.Sleep(1000);
                Console.WriteLine("1");
                System.Threading.Thread.Sleep(1000);
            }

            Console.Clear();

            string teamIntro;
            var theAnswer = Answers.GetAnswer();

            bool IsOdd(int value)
            {
                return value % 2 != 0;
            }

            int t1Score = 0;
            int t2Score = 0;

            List<string> Profanity = new List<string>();
            Profanity.Add("fuck");
            Profanity.Add("shit");
            Profanity.Add("bollocks");
            Profanity.Add("wank");
            Profanity.Add("cunt");
            Profanity.Add("tosser");
            Profanity.Add("bastard");
            Profanity.Add("fanny");
            Profanity.Add("faggot");
            Profanity.Add("arse");

            for (int i = 0; i < 10; i++)
            {
                Console.Clear();
                var myQuestion = theAnswer[i+1];

                if(IsOdd(i+1))
                {
                    if (i == 8)
                    {
                        teamIntro = ($"{Team1} time for your final question.");
                    }
                    else
                    {
                        switch (array[i])
                        {
                            case 1:
                                teamIntro = ($"{Team1} you're up!");
                                break;
                            case 2:
                                teamIntro = ($"{Team1} it's your turn.");
                                break;
                            case 3:
                                teamIntro = ($"{Team1} this question's yours.");
                                break;
                            case 4:
                                teamIntro = ($"{Team1} let's see if you can get this one.");
                                break;
                            case 5:
                                teamIntro = ($"{Team1}! I've picked this one especially for you...");
                                break;
                            case 6:
                                teamIntro = ($"{Team1} this is a tough one!");
                                break;
                            case 7:
                                teamIntro = ($"{Team1} whenever you're ready, here's your question:");
                                break;
                            default:
                                teamIntro = ($"{Team1} try this one on for size:");
                                break;
                        }
                    }
                }
                else
                {
                    if (i == 9)
                    {
                        teamIntro = ($"{Team2} time for your final question.");
                    }
                    else
                    {
                        switch (array[i])
                        {
                            case 1:
                                teamIntro = ($"{Team2} you're up!");
                                break;
                            case 2:
                                teamIntro = ($"{Team2} it's your turn.");
                                break;
                            case 3:
                                teamIntro = ($"{Team2} this question's yours.");
                                break;
                            case 4:
                                teamIntro = ($"{Team2} let's see if you can get this one.");
                                break;
                            case 5:
                                teamIntro = ($"{Team2}! I've picked this one especially for you...");
                                break;
                            case 6:
                                teamIntro = ($"{Team2} this is a tough one!");
                                break;
                            case 7:
                                teamIntro = ($"{Team2} whenever you're ready, here's your question:");
                                break;
                            default:
                                teamIntro = ($"{Team2} try this one on for size:");
                                break;
                        }
                    }
                }

                text = ($"{team}{myQuestion.NumText} Question:\n\n{teamIntro}\n\n{myQuestion.Question}");
                Console.WriteLine(text);

                if (voiceYN == true)
                {
                    synth.Speak(text);
                }

                blank:
                string myAnswer = Console.ReadLine();
            //This is the third
                if (string.IsNullOrEmpty(myAnswer))
                {
                    goto blank;
                }


                result = string.Equals(myAnswer, myQuestion.Answer, StringComparison.InvariantCultureIgnoreCase);

                if (result == true)
                {
                    if (IsOdd(i + 1))
                    {
                        t1Score = t1Score + 1;
                    }
                    else
                    {
                        t2Score = t2Score + 1;
                    }
                }
                else
                {          
                    for (int p = 0; p < Profanity.Count; p++)
                    {
                        if (myAnswer.ToLower().Contains(Profanity[p]))
                        {
                            result = true;
                            break;
                        }
                    }



                    if (result == true)
                    {
                        Console.WriteLine("\nProfanity is not accepted! 1 point has been deducted from your team's score");
                        if (IsOdd(i))
                        {
                            t1Score = t1Score - 1;
                        }
                        else
                        {
                            t2Score = t2Score - 1;
                        }

                    System.Threading.Thread.Sleep(2000);
                    }
                }




            }




        }
    }
}

Teams Class:

using System.Collections.Generic;

namespace PopQuiz
{

    public class Team
    {
        public string Name { get; set; }

        public Team(string name)
        {
            Name = name;
        }

           public static Dictionary<int, Team> GetPlayer()
        {
            var player = new Dictionary<int, Team>();
            var myPlayer = new Team("Name1                     ");
            player.Add(1, myPlayer);
            myPlayer = new Team("Name2                     ");
            player.Add(2, myPlayer);
            myPlayer = new Team("Name3                     ");
            player.Add(3, myPlayer);
            myPlayer = new Team("Name4                     ");
            player.Add(4, myPlayer);
            myPlayer = new Team("Name5                     ");
            player.Add(5, myPlayer);
            myPlayer = new Team("Name6                     ");
            player.Add(6, myPlayer);
            myPlayer = new Team("Name7                     ");
            player.Add(7, myPlayer);
            myPlayer = new Team("Name8                     ");
            player.Add(8, myPlayer);


            return player;
        }
    }
}

Answers Class:

using System.Collections.Generic;

namespace PopQuiz
{
    public class Answers
    {
        public string Question { get; set; }
        public string Answer { get; set; }
        public string NumText { get; set; }


        public Answers(string numText, string question, string answer)
        {
            NumText = numText;
            Question = question;
            Answer = answer;
        }

        public static Dictionary<int, Answers> GetAnswer()
        {
            var question = new Dictionary<int, Answers>();
            var theAnswer = new Answers("First","Who?", "...");
            question.Add(1, theAnswer);
            theAnswer = new Answers("Second","What?", "...");
            question.Add(2, theAnswer);
            theAnswer = new Answers("Third","Where?", "...");
            question.Add(3, theAnswer);
            theAnswer = new Answers("Fourth","When?", "...");
            question.Add(4, theAnswer);
            theAnswer = new Answers("Fifth","How?", "...");
            question.Add(5, theAnswer);
            theAnswer = new Answers("Sixth", "Why?", "...");
            question.Add(6, theAnswer);
            theAnswer = new Answers("Seventh", "Which?", "...");
            question.Add(7, theAnswer);
            theAnswer = new Answers("Eighth", "With whom?", "...");
            question.Add(8, theAnswer);
            theAnswer = new Answers("Ninth", "What also?", "...");
            question.Add(9, theAnswer);
            theAnswer = new Answers("Tenth", "Done now?", "...");
            question.Add(10, theAnswer);



            return question;
        }

    }
}
\$\endgroup\$
  • \$\begingroup\$ Please add a few words about what this quiz is about etc. \$\endgroup\$ – t3chb0t May 15 '17 at 11:16
  • \$\begingroup\$ @t3chb0t It was just an idea for me to practice code. I am making the move from VBA to C# and ASP.net. I use the fisher-yates shuffle for randomising an array without duplication and dictionaries for question data (Not sure but perhaps a list here is better). i am a self-learner so I will just create random stuff to practice code until i am able to create something with a purpose... Just hoping for some pointers really and to see if there is a better way to check for Null or Empty Console.ReadLine();? \$\endgroup\$ – Glitch_Doctor May 15 '17 at 11:20
  • 2
    \$\begingroup\$ no worries, your first question is fine ;-) just write a short explanation of what this pop-quiz is about and it'll be perfect. \$\endgroup\$ – t3chb0t May 15 '17 at 11:27
  • \$\begingroup\$ That is not a valid fisher yates \$\endgroup\$ – paparazzo May 15 '17 at 12:22
  • \$\begingroup\$ @Paparazzi Apologies, it was a search engine job ^^ it does the job though ;] \$\endgroup\$ – Glitch_Doctor May 15 '17 at 13:04
6
\$\begingroup\$

I'm just going to point out things in whatever random order I see them in. Mind you there is so much going on with this code, that I'll just be scratching the surface.

  • All your if (x == true) or if (x == false) comparisons would be better written as if (x) or if (!x)
  • The whitespace in the names var myPlayer = new Team("Name1 ") shouldn't be added there, because the whitespace isn't part of the name. Do your formatting when you output it.

  • The code below creates a new string (myAnswer.ToLower()) for every profanity:

for (int p = 0; p < Profanity.Count; p++)
{
    if (myAnswer.ToLower().Contains(Profanity[p]))
    {
        result = true;
        break;
    }
}

You could only do a ToLower() once and compare that to each profanity. Better yet, don't do ToLower(), and instead do a case insensitive comparison: if (myAnswer.IndexOf(Profanity[p], StringComparison.OrdinalIgnoreCase) >= 0) Better yet again, don't do this loop at all and use linq: result = Profanity.Any(p => myAnswer.IndexOf(p, StringComparison.OrdinalIgnoreCase) >= 0);. And then go one step further and change the name result to something more useful: var containsProfanity = Profanity.Any(p => myAnswer.IndexOf(p, StringComparison.OrdinalIgnoreCase) >= 0);

Although I don't really like the way it checks in the first place because it will pick up legit words as well - for example, Arsenal will be considered profanity.

  • Way, way too much going on in Main(). Pretty much everything in there, except maybe setting up the colours and title, should be in separate methods, which in turn should probably be in other classes.

  • var thePlayers = Team.GetPlayer(); -- GetPlayer() suggests a single player (but which one?), variable name suggests it returns a collection. Inconsistent naming.

  • You don't need to declare all your variables at the top of the method. Declare them generally right before you use them, unless it's clearer to do otherwise. In a method this big (Main()), it's not clear to have them all at the top.

  • Surely there must be a better way to get a player:

var myPlayer = thePlayers[array[7]];
captains = myPlayer.Name;
myPlayer = thePlayers[array[3]];

I can't even understand what's going on there. You're accessing a player at a hard coded array index, you know that index 7 will always be the captain, and overwriting the myPlayer variable. Right, and who is player index 3? Why is captains plural when it's assigned a single string? You really need to encapsulate this logic in methods that explain what they're doing, for example:

var captain = team.GetCaptain();
var player = team.GetPlayer("Bob");

Etc. This goes for basically everything else in Main(), all this ugly array logic should be hidden behind methods, but this one in particular stood out to me.

\$\endgroup\$
  • \$\begingroup\$ Thank you for the answer, this is exactly what I needed. I knew it was messy but C# is so different to VBA that it's a little hard to know the common practice. I am just taking notes so have a +1 for the time being :] \$\endgroup\$ – Glitch_Doctor May 15 '17 at 11:39
  • \$\begingroup\$ Good point about the profanity catch there too but I have thought of that. i know it needs improving but I am just going to ensure that no answers contain or could contain the profanity strings. I just wanted the profanity catch in there as i am going to use it in the next team meeting just a bit of fun. \$\endgroup\$ – Glitch_Doctor May 15 '17 at 13:41
  • \$\begingroup\$ Update: Thanks for the tips on this last month. I've come a long way from this rubbish I produced. I have just completed my first fully functional web app in ASP.NET CORE MVC... I might throw up the API for review at some point but I want to add some more functionality first to test it out. \$\endgroup\$ – Glitch_Doctor Jun 19 '17 at 10:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.