Ejemplo n.º 1
0
        static void Main(string[] args)
        {
            Console.OutputEncoding = Encoding.UTF8;

            var solvers = new Dictionary <string, ISraixService>();

            foreach (var type in typeof(ButtonSolver).Assembly.GetExportedTypes().Where(typeof(ISraixService).IsAssignableFrom))
            {
                solvers.Add(type.Name, (ISraixService)Activator.CreateInstance(type));
            }

            var user = new User("User", new Bot());

            string evaluate(string serviceName, string text)
            {
                return(solvers[serviceName].Process(text, null, new RequestProcess(new RequestSentence(new Request(text, user, user.Bot), text), 0, false)));
            }

            while (true)
            {
                Console.Write("> ");
                var fields = Console.ReadLine().Split((char[]?)null, StringSplitOptions.RemoveEmptyEntries);

                try {
                    var text = string.Join(" ", fields.Skip(1));
                    switch (fields[0].ToLower())
                    {
                    case "reset":
                        user = new User("User", new Bot());
                        break;

                    case "set":
                        user.Predicates[fields[1]] = fields[2];
                        break;

                    case "button":
                        if (fields[1].Equals("rules", StringComparison.CurrentCultureIgnoreCase))
                        {
                            var rules = ButtonSolver.GetRules(int.Parse(fields[2]));

                            for (int i = 0; i < rules.InitialRules.Length; ++i)
                            {
                                Console.WriteLine($"{i + 1}. {rules.InitialRules[i]}");
                            }

                            Console.WriteLine();
                            Console.ForegroundColor = ConsoleColor.White;
                            Console.WriteLine("Releasing a Held Button");
                            Console.ResetColor();

                            for (int i = 0; i < rules.HeldRules.Length; ++i)
                            {
                                Console.WriteLine(rules.HeldRules[i].ToString());
                            }
                            Console.WriteLine();
                        }
                        else
                        {
                            Console.WriteLine(evaluate(nameof(ButtonSolver), text));
                        }
                        break;

                    case "complicatedwires":
                        if (fields[1].Equals("rules", StringComparison.CurrentCultureIgnoreCase))
                        {
                            var rules = ComplicatedWiresSolver.GetRules(int.Parse(fields[2]));

                            for (int i = 0; i < rules.Length; ++i)
                            {
                                Console.WriteLine($"{(Solvers.ComplicatedWiresSolver.Flags) i}: {rules[i]}");
                            }
                            Console.WriteLine();
                        }
                        else
                        {
                            Console.WriteLine(evaluate(nameof(ComplicatedWiresSolver), text));
                        }
                        break;

                    case "keypad":
                        if (fields[1].Equals("rules", StringComparison.CurrentCultureIgnoreCase))
                        {
                            var columns = KeypadSolver.GetColumns(int.Parse(fields[2]));

                            var glyphCharacters = new[] {
                                '©', '★', '☆', 'ټ', 'Җ', 'Ω', 'Ѭ', 'ѽ', 'ϗ', 'ϫ',
                                'Ϭ', 'Ϟ', 'Ѧ', 'æ', 'Ԇ', 'Ӭ', '҈', 'Ҋ', 'Ѯ', '¿',
                                '¶', 'Ͼ', 'Ͽ', 'Ψ', 'Ѫ', 'Ҩ', '҂', 'Ϙ', 'ζ', 'ƛ',
                                'Ѣ'
                            };

                            for (int i = 0; i < columns.Length; ++i)
                            {
                                Console.WriteLine(string.Join("", columns[i].Select(g => g.ToString().PadRight(14))));
                            }
                            Console.WriteLine();
                        }
                        else
                        {
                            Console.WriteLine(evaluate(nameof(KeypadSolver), text));
                        }
                        break;

                    case "knob":
                        if (fields[1].Equals("rules", StringComparison.CurrentCultureIgnoreCase))
                        {
                            var rules = KnobSolver.GetRules(int.Parse(fields[2]));

                            for (int i = 0; i < 4; ++i)
                            {
                                Console.ForegroundColor = ConsoleColor.White;
                                Console.WriteLine($"{(Solvers.KnobSolver.Position) i} Position:");
                                Console.ResetColor();

                                var rule0 = rules[i * 2];
                                var rule1 = rules[i * 2 + 1];

                                for (int j = 0; j < 6; ++j)
                                {
                                    Console.Write(rule0.Lights[j] ? 'X' : '.');
                                    Console.Write(' ');
                                }
                                Console.Write("    ");
                                for (int j = 0; j < 6; ++j)
                                {
                                    Console.Write(rule1.Lights[j] ? 'X' : '.');
                                    Console.Write(' ');
                                }
                                Console.WriteLine();
                                for (int j = 6; j < 12; ++j)
                                {
                                    Console.Write(rule0.Lights[j] ? 'X' : '.');
                                    Console.Write(' ');
                                }
                                Console.Write("    ");
                                for (int j = 6; j < 12; ++j)
                                {
                                    Console.Write(rule1.Lights[j] ? 'X' : '.');
                                    Console.Write(' ');
                                }
                                Console.WriteLine();
                                Console.WriteLine();
                            }
                        }
                        else
                        {
                            Console.WriteLine(evaluate(nameof(KnobSolver), text));
                        }
                        break;

                    case "maze":
                        char boxDrawingChar(Solvers.MazeSolver.MazeFlags flags)
                        {
                            switch (flags)
                            {
                            case 0: return(' ');

                            case North: return('╵');

                            case West: return('╴');

                            case West | North: return('┘');

                            case East: return('╶');

                            case East | North: return('└');

                            case East | West: return('─');

                            case East | West | North: return('┴');

                            case South: return('╷');

                            case South | North: return('│');

                            case South | West: return('┐');

                            case South | West | North: return('┤');

                            case South | East: return('┌');

                            case South | East | North: return('├');

                            case South | East | West: return('┬');

                            case South | East | West | North: return('┼');

                            default: return('?');
                            }
                        }

                        if (fields[1].Equals("rules", StringComparison.CurrentCultureIgnoreCase))
                        {
                            var mazes = MazeSolver.GetMazes(int.Parse(fields[2]));

                            for (int i = 0; i < mazes.Length; ++i)
                            {
                                var maze = mazes[i];
                                var maxx = maze.Cells.GetUpperBound(0);
                                var maxy = maze.Cells.GetUpperBound(1);

                                Console.ForegroundColor = ConsoleColor.White;
                                Console.WriteLine($"Maze {i + 1}");
                                Console.ResetColor();

                                for (int y = 0; ; ++y)
                                {
                                    for (int x = 0; ; ++x)
                                    {
                                        // Corner tile
                                        Solvers.MazeSolver.MazeFlags flags = 0;
                                        if (y > 0 && (x <= 0 || !maze.Cells[x - 1, y - 1].HasFlag(East)))
                                        {
                                            flags |= North;
                                        }
                                        if (x > 0 && (y <= 0 || !maze.Cells[x - 1, y - 1].HasFlag(South)))
                                        {
                                            flags |= West;
                                        }
                                        if (x <= maxx && (y <= 0 || !maze.Cells[x, y - 1].HasFlag(South)))
                                        {
                                            flags |= East;
                                        }
                                        if (y <= maxy && (x <= 0 || !maze.Cells[x - 1, y].HasFlag(East)))
                                        {
                                            flags |= South;
                                        }
                                        Console.Write(boxDrawingChar(flags));

                                        if (x > maxx)
                                        {
                                            break;
                                        }
                                        // Horizontal border tile
                                        flags = 0;
                                        if (y <= 0 || !maze.Cells[x, y - 1].HasFlag(South))
                                        {
                                            flags |= West | East;
                                        }
                                        Console.Write(boxDrawingChar(flags));
                                    }
                                    Console.WriteLine();

                                    if (y > maxy)
                                    {
                                        break;
                                    }
                                    for (int x = 0; ; ++x)
                                    {
                                        // Vertical border tile
                                        Solvers.MazeSolver.MazeFlags flags = 0;
                                        if (x <= 0 || !maze.Cells[x - 1, y].HasFlag(East))
                                        {
                                            flags |= North | South;
                                        }
                                        Console.Write(boxDrawingChar(flags));

                                        if (x > maxx)
                                        {
                                            break;
                                        }
                                        // Space tile
                                        if (maze.Indicators.Contains(new Solvers.MazeSolver.Point(x, y)))
                                        {
                                            Console.ForegroundColor = ConsoleColor.Green;
                                            Console.Write($"O");
                                            Console.ResetColor();
                                        }
                                        else
                                        {
                                            Console.Write('·');
                                        }
                                    }
                                    Console.WriteLine();
                                }

                                Console.WriteLine();
                            }
                        }
                        else
                        {
                            Console.WriteLine(evaluate(nameof(MazeSolver), text));
                        }
                        break;

                    case "memory":
                        if (fields[1].Equals("rules", StringComparison.CurrentCultureIgnoreCase))
                        {
                            var rules = MemorySolver.GetRules(int.Parse(fields[2]));

                            for (int i = 0; i <= rules.GetUpperBound(0); ++i)
                            {
                                Console.ForegroundColor = ConsoleColor.White;
                                Console.WriteLine($"Stage {i + 1}:");
                                Console.ResetColor();

                                for (int j = 0; j < 4; ++j)
                                {
                                    Console.WriteLine($"If the display is {j + 1}, {rules[i, j]}.");
                                }
                                Console.WriteLine();
                            }
                        }
                        else
                        {
                            Console.WriteLine(evaluate(nameof(MemorySolver), text));
                        }
                        break;

                    case "morsecode":
                        if (fields[1].Equals("rules", StringComparison.CurrentCultureIgnoreCase))
                        {
                            var entries = MorseCodeSolver.GetRules(int.Parse(fields[2])).OrderBy(e => e.Value);

                            Console.ForegroundColor = ConsoleColor.White;
                            Console.WriteLine($"If the word is:  Respond at frequency:");
                            Console.ResetColor();
                            foreach (var entry in entries)
                            {
                                Console.WriteLine($"{entry.Key,-15}  {entry.Value} MHz");
                            }
                            Console.WriteLine();
                        }
                        else
                        {
                            Console.WriteLine(evaluate(nameof(MorseCodeSolver), text));
                        }
                        break;

                    case "password":
                        if (fields[1].Equals("rules", StringComparison.CurrentCultureIgnoreCase))
                        {
                            var words = PasswordSolver.GetWords(int.Parse(fields[2]));

                            for (int i = 0; i < words.Length; ++i)
                            {
                                Console.Write(words[i]);
                                if (i % 5 == 4)
                                {
                                    Console.WriteLine();
                                }
                                else
                                {
                                    Console.Write("  ");
                                }
                            }
                            Console.WriteLine();
                        }
                        else
                        {
                            Console.WriteLine(evaluate(nameof(PasswordSolver), text));
                        }
                        break;

                    case "simonsays":
                        if (fields[1].Equals("rules", StringComparison.CurrentCultureIgnoreCase))
                        {
                            var colours = SimonSaysSolver.GetRules(int.Parse(fields[2]));

                            for (int i = 1; i >= 0; --i)
                            {
                                Console.ForegroundColor = ConsoleColor.White;
                                Console.WriteLine($"If the serial number {(i > 0 ? "contains" : "does not contain")} a vowel:");
                                Console.ResetColor();
                                Console.WriteLine($"            Red flash     Blue flash    Green flash   Yellow flash");
                                for (int j = 0; j < 3; ++j)
                                {
                                    Console.Write((j == 0 ? "No strikes" : j == 1 ? "1 strike" : "2+ strikes").PadRight(12));
                                    for (int k = 0; k < 4; ++k)
                                    {
                                        Console.Write(colours[i, j, k].ToString().PadRight(14));
                                    }
                                    Console.WriteLine();
                                }
                                Console.WriteLine();
                            }
                        }
                        else
                        {
                            Console.WriteLine(evaluate(nameof(SimonSaysSolver), text));
                        }
                        break;

                    case "whosonfirst":
                        if (fields[1].Equals("rules", StringComparison.CurrentCultureIgnoreCase))
                        {
                            var ruleSet = WhosOnFirstSolver.GetRules(int.Parse(fields[2]));

                            Console.ForegroundColor = ConsoleColor.White;
                            Console.WriteLine($"Step 1:");
                            Console.ResetColor();

                            int           count = 0;
                            StringBuilder builder1 = new StringBuilder(), builder2 = new StringBuilder(), builder3 = new StringBuilder(), builder4 = new StringBuilder();
                            foreach (var entry in ruleSet.DisplayRules)
                            {
                                builder1.Append(entry.Key.PadRight(10));
                                builder2.Append($" {(entry.Value == 0 ? 'O' : '.')}   {(entry.Value == 1 ? 'O' : '.')}    ");
                                builder3.Append($" {(entry.Value == 2 ? 'O' : '.')}   {(entry.Value == 3 ? 'O' : '.')}    ");
                                builder4.Append($" {(entry.Value == 4 ? 'O' : '.')}   {(entry.Value == 5 ? 'O' : '.')}    ");

                                ++count;
                                if (count % 6 == 0)
                                {
                                    Console.WriteLine(builder1.ToString());
                                    Console.WriteLine(builder2.ToString());
                                    Console.WriteLine(builder3.ToString());
                                    Console.WriteLine(builder4.ToString());
                                    Console.WriteLine();
                                    builder1.Clear();
                                    builder2.Clear();
                                    builder3.Clear();
                                    builder4.Clear();
                                }
                            }
                            if (count % 6 > 0)
                            {
                                Console.WriteLine(builder1.ToString());
                                Console.WriteLine(builder2.ToString());
                                Console.WriteLine(builder3.ToString());
                                Console.WriteLine(builder4.ToString());
                                Console.WriteLine();
                            }

                            Console.ForegroundColor = ConsoleColor.White;
                            Console.WriteLine($"Step 2:");
                            Console.ResetColor();

                            foreach (var entry in ruleSet.ButtonRules)
                            {
                                Console.WriteLine($"{$"\"{entry.Key}\":",-12}{string.Join(", ", entry.Value)}");
                            }

                            Console.WriteLine();
                        }
                        else
                        {
                            Console.WriteLine(evaluate(nameof(WhosOnFirstSolver), text));
                        }
                        break;

                    case "wires":
                        if (fields[1].Equals("rules", StringComparison.CurrentCultureIgnoreCase))
                        {
                            var rules = WiresSolver.GetRules(int.Parse(fields[2]));

                            for (int i = 0; i < rules.Length; ++i)
                            {
                                Console.ForegroundColor = ConsoleColor.White;
                                Console.WriteLine($"{i + 3} wires");
                                Console.ResetColor();

                                var otherwise = false;
                                foreach (var rule in rules[i])
                                {
                                    if (otherwise)
                                    {
                                        Console.Write("Otherwise, ");
                                    }
                                    otherwise = true;
                                    Console.WriteLine(rule.ToString());
                                }

                                Console.WriteLine();
                            }
                        }
                        else
                        {
                            Console.WriteLine(evaluate(nameof(WiresSolver), text));
                        }
                        break;

                    case "wiresequences":
                        if (fields[1].Equals("rules", StringComparison.CurrentCultureIgnoreCase))
                        {
                            string describeInstruction(Solvers.WireSequencesSolver.Instruction instruction)
                            {
                                switch ((int)instruction)
                                {
                                case 0: return("never");

                                case 1: return("A");

                                case 2: return("B");

                                case 3: return("A or B");

                                case 4: return("C");

                                case 5: return("A or C");

                                case 6: return("B or C");

                                case 7: return("A, B or C");

                                default: return(instruction.ToString());
                                }
                            }

                            var rules = WireSequencesSolver.GetRules(int.Parse(fields[2]));

                            Console.ForegroundColor = ConsoleColor.White;
                            Console.WriteLine("         Red        Blue       Black");
                            Console.ResetColor();
                            for (int i = 0; i < 9; ++i)
                            {
                                string ordinal;
                                switch (i)
                                {
                                case 0: ordinal = "first"; break;

                                case 1: ordinal = "second"; break;

                                case 2: ordinal = "third"; break;

                                case 3: ordinal = "fourth"; break;

                                case 4: ordinal = "fifth"; break;

                                case 5: ordinal = "sixth"; break;

                                case 6: ordinal = "seventh"; break;

                                case 7: ordinal = "eighth"; break;

                                default: ordinal = "ninth"; break;
                                }
                                Console.WriteLine($"{ordinal,-7}  {describeInstruction(rules.RedRules[i]),-9}  {describeInstruction(rules.BlueRules[i]),-9}  {describeInstruction(rules.BlackRules[i])}");
                            }
                            Console.WriteLine();
                        }
                        else
                        {
                            Console.WriteLine(evaluate(nameof(WireSequencesSolver), text));
                        }
                        break;

                    case "q":
                        return;
                    }
                } catch (Exception ex) {
                    Console.Error.WriteLine(ex);
                }
            }
        }