/// <summary>
        /// Custom Input Action for the 'Breaker of Chains' problem
        /// </summary>
        /// <param name="input">The user input which triggered the custom action</param>
        /// <param name="southeros"></param>
        /// <returns></returns>
        /// <remarks>We don't particularly require the input data in this function but we keep it anyway to match the function signature</remarks>
        public string CustomInputAction(string input, ISoutheros southeros)
        {
            // Once a ruler has been found, we no longer need to hold a ballot
            if (southeros.RulingKingdom != null)
            {
                return(string.Format(Utility.RulerCrownedMessage, southeros.RulingKingdom.Name));
            }

            // Declare local variables
            var output           = string.Empty;
            var noOfCompetitors  = 0;
            var maxBallotRounds  = 1000;
            var messagesToChoose = 6;

            // Read the list of competitors from the user
            var possibleCandidates = console.ReadLine().Trim().Replace(',', ' ').Split(" ", StringSplitOptions.RemoveEmptyEntries);

            // Try parsing the user input into valid kingdoms
            foreach (var candidate in possibleCandidates)
            {
                if (!string.IsNullOrWhiteSpace(candidate) &&
                    Enum.TryParse(candidate, true, out Kingdoms competingKingdom))
                {
                    southeros.AllKingdoms[competingKingdom].IsCompeting = true;
                    noOfCompetitors++;
                }
                else
                {
                    output += string.Format(Utility.InvalidKingdomMessage, candidate);
                }
            }

            // We need atleast two kingdoms competing for the crown
            if (noOfCompetitors < 2)
            {
                output += Utility.NoCompetingKingdomsMessage;
            }
            // and atmost one less than all of them
            else if (noOfCompetitors < Enum.GetValues(typeof(Kingdoms)).Length)
            {
                // Summon high priest
                var highPriest = new HighPriest(messagesToChoose, maxBallotRounds, console);
                // FindRulerByBallot return false if we don't have a ruler after maxBallotRounds

                if (!highPriest.HoldBallot(southeros))
                {
                    output += Utility.BallotTookTooLongMessage;
                }
            }
            // If all the kingdoms compete, we can't proceed
            else
            {
                output += Utility.TooManyKingdomsMessage;
            }

            return(output);
        }
示例#2
0
        // Custom Input Action for the 'A Golden Crown' problem
        public string CustomInputAction(string input, ISoutheros southeros)
        {
            // Declare local variables
            var output = string.Empty;
            // The only competing kingdom as per the problem is the SpaceKingdom (this can
            // be changed here any time)
            var competingKingdom = Kingdoms.Space;
            // Required right to rule is the number of kingdoms the competingKingdom kingdom
            // needs to be allied with in order to be crowned as the ruler
            var reqRightToRule = 3;

            // Give the gorilla king of the Space kingdom a name
            southeros.AllKingdoms[Kingdoms.Space].King = "King Shan";

            // Try parsing the input into target kingdom and message
            var index       = input.IndexOf('"');
            var recipient   = input.Substring(0, index).Trim(new char[] { ' ', ',' });
            var messageText = input.Substring(index + 1, input.LastIndexOf('"') - index - 1);

            // Try parsing the target kingdom to verify target is valid
            if (Enum.TryParse(recipient, true, out Kingdoms recipientKingdom))
            {
                // Create message object
                var message = new Message(competingKingdom, recipientKingdom, messageText);

                // Send out message
                southeros.AllKingdoms[competingKingdom].SendMessage(southeros.AllKingdoms[recipientKingdom], message);

                // Check if the competeing kingdom now has the required number of allies
                if (southeros.AllKingdoms[competingKingdom].Allies.Count >= reqRightToRule)
                {
                    // If so, set the value for the ruling kingdom
                    southeros.RulingKingdom = southeros.AllKingdoms[competingKingdom];
                }
            }
            // If target is invalid, return appropriate error message
            else
            {
                output = string.Format(Utility.InvalidKingdomMessage, recipient);
            }

            return(output);
        }
示例#3
0
        /// <summary>
        /// Finds the ruler of Southeros using a ballot system
        /// </summary>
        /// <param name="southeros">Reference to a ISoutheros implemented class object</param>
        /// <returns>Returns a boolean denoting whether a king was crowned or not</returns>
        public bool HoldBallot(ISoutheros southeros)
        {
            // Randomizer to choose message to write
            var rnd = new Random();

            //Ballot round
            int round = 0;

            // The drawing from the ballot goes on until a winner is decided or we reach maxRounds
            while (southeros.RulingKingdom == null &&
                   ++round <= maxRounds)
            {
                // Get a new ballot box
                var ballotBox = new BallotBox();

                // Round up all kingdoms competing for the throne
                var competingKingdoms = southeros.AllKingdoms.Where(kv => kv.Value.IsCompeting).Select(kv => kv.Key).ToList();

                // Each competing kingdom composes messages...
                foreach (var competitor in competingKingdoms)
                {
                    // ...for all the other kingdoms
                    foreach (var reciver in southeros.AllKingdoms.Keys)
                    {
                        // ...except itself ofcourse ¯\_(ツ)_/¯
                        if (reciver == competitor)
                        {
                            continue;
                        }
                        var newRequest = new Message(competitor, reciver, Utility.listOfMessages[rnd.Next(Utility.listOfMessages.Count)]);
                        ballotBox.DropMessage(newRequest);
                    }
                }

                // The High Priest of Southeros chooses the messages to send out
                var choosenMessages = PickRandomMessages(ballotBox);

                // Hand over the messages
                foreach (var message in choosenMessages)
                {
                    southeros.AllKingdoms[message.Sender].SendMessage(southeros.AllKingdoms[message.Recipient], message);
                }

                // Declare results
                console.WriteLine($"{Environment.NewLine}Results after round {Utility.IntegerToWritten(round)} ballot count");

                // Variable to store max allies by any kingdom
                var maxAllies = 0;

                foreach (var competitor in competingKingdoms)
                {
                    var allyCount = southeros.AllKingdoms[competitor].Allies.Count;

                    console.WriteLine($"Allies for {competitor} : {allyCount}");

                    maxAllies = allyCount > maxAllies ? allyCount : maxAllies;
                }

                // Find the kingdom(s) with the most allies
                var leadingKingdoms = southeros.AllKingdoms.Where(kv => kv.Value.IsCompeting && kv.Value.Allies.Count == maxAllies);

                // If there is a tie
                if (leadingKingdoms.Count() > 1)
                {
                    // Clear the list of old competitors
                    competingKingdoms.Clear();

                    // Create a new list comprising of the kingdoms there was a tie between
                    competingKingdoms.AddRange(leadingKingdoms.Select(kv => kv.Key));

                    // Break all alliances
                    foreach (var kingdom in southeros.AllKingdoms.Values)
                    {
                        kingdom.BreakAlliances();
                    }
                }
                // If not...
                else
                {
                    // ...we declare the winner
                    southeros.RulingKingdom = leadingKingdoms.FirstOrDefault().Value;
                }
            }

            return(southeros.RulingKingdom != null);
        }