Dynamicznie wypełniający się Switch-case.

0

Cześć, piszę sobie gierkę Snejka w C# żeby ogarnąć obiektówkę. W trakcie pracy postanowiłem, że napisze sobie klase MENU która będzie uniwersalna, że będę do niej podawał tablice dwuwymiarową w której będą zawarte opcje wyboru i wygeneruje mi ona pełne menu. Problem się pojawia, gdy mam switch który musi się sam wygenerować podczas działania programu, bo nie wiem ile będę miał opcji. Próbowałem z pętlą ale to nie działa. Czy jedyną opcją jest dziedziczenie i polimorfizm.. Pomóżcie bo nie mogę ruszyć dalej ;d


```using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SNAKE
{
    /// <summary>
    /// To create menu you need to create string [,] array to fill menu.
    /// </summary>
    /// <param name = "PossitionsListArray"> String Array with menu list</param>
    class Menu
    {
        private double HowMuchFieldsInArray;
        /// <summary>
        /// 1 column is the first menu options and second is the develop of the first column option
        /// </summary>
        private string[,] MenuOptions;


        public Menu(string[,] PossitionsListArray )
        {
             MenuOptions = PossitionsListArray;
             HowMuchFieldsInArray = MenuOptions.Length;
             HowMuchFieldsInArray = Math.Sqrt(HowMuchFieldsInArray);



        }
       


        public int CreateMenu ()
        {

            int position = 1;
            int status = 0;
            
            ConsoleKeyInfo cki;
            do
            {


                switch (position)
                {



                    case 1:
                        {
                            Console.WriteLine(MenuOptions[0, 0]);
                            Console.BackgroundColor = ConsoleColor.White;
                            Console.WriteLine(MenuOptions[1, 0]);
                            Console.BackgroundColor = ConsoleColor.Black;
                            Console.WriteLine(MenuOptions[2, 0]);
                            Console.WriteLine(MenuOptions[3, 0]);


                            break;
                        }

                    case 2:
                        {
                            Console.WriteLine(MenuOptions[0, 0]);
                            Console.WriteLine(MenuOptions[1, 0]);
                            Console.BackgroundColor = ConsoleColor.White;
                            Console.WriteLine(MenuOptions[2, 0]);
                            Console.BackgroundColor = ConsoleColor.Black;
                            Console.WriteLine(MenuOptions[3, 0]);



                            break;
                        }

                    case 3:
                        {
                            Console.WriteLine(MenuOptions[0, 0]);
                            Console.WriteLine(MenuOptions[1, 0]);
                            Console.WriteLine(MenuOptions[2, 0]);
                            Console.BackgroundColor = ConsoleColor.White;
                            Console.WriteLine(MenuOptions[3, 0]);
                            Console.BackgroundColor = ConsoleColor.Black;



                            break;


                        }

                }
                        cki = Console.ReadKey();

                switch (cki.Key)
                {


                    case ConsoleKey.UpArrow:
                        {
                            if (position == 1)
                            {
                                break;
                            }
                            else
                            {
                                position--;
                                break;
                            }

                        }

                    case ConsoleKey.DownArrow:
                        {
                            if (position == 3)
                            {
                                break;
                            }
                            else
                            {
                                position++;
                                break;
                            }

                        }
                    case ConsoleKey.Enter:
                        {
                            status = position;
                            break;
                        }

                };


                Console.Clear();


            } while (cki.Key != ConsoleKey.Enter);


            return status; //zwracam status 1- new game / 2- opcje / 3- wyjście z gry
                
            }







        }


    }

Z góry dziękuje za odpowiedzi.

2

A gdyby zamiast switcha, to Dictionary<ConsoleKey, Action>?

https://stackoverflow.com/questions/33107026/dynamic-switch-cases

0

dobra rozkminiłem to..

  public Menu(string[,] PossitionsListArray)
        {
            MenuOptions = PossitionsListArray;
            HowMuchFieldsInArray = MenuOptions.Length;
            HowMuchFieldsInArray = Math.Sqrt(HowMuchFieldsInArray);

            for (int i = 0; i < HowMuchFieldsInArray; i++)
            {
                
                OpcjeMenu.Add(i, () =>
                {
                    for (int a=0; a<HowMuchFieldsInArray; a++)
                    {

                        Console.WriteLine(i);
                        Console.WriteLine(a);

                        if (a == i)
                        {
                            Console.WriteLine("dupa");
                            Console.BackgroundColor = ConsoleColor.White;

                        }
                        else if (a-1 == i)
                        {
                            Console.BackgroundColor = ConsoleColor.Black;
                        }
                        Console.WriteLine(MenuOptions[a, 0]);
                  
                    }
         
                });
            }
       


            


        }

Wiem, że to nie temat postu ale teraz mi nie działa podświetlanie na biało.. Coś z pętlą chyba?
.. Czemu w konsoli mi się wyświetla cały czas 4? nie powinno być po kolei od 0 do 3?

2

Czemu w konsoli mi się wyświetla cały czas 4? nie powinno być po kolei od 0 do 3?

Nie, jest poprawnie. Poczytaj o domknięciach (closures). Do każdego delegata przekazujesz zmienną i, a ona po wykonaniu się pętli ma wartość 4. I przy wywoływaniu ta wartość będzie użyta.

https://blogs.msdn.microsoft.com/ericlippert/2009/11/12/closing-over-the-loop-variable-considered-harmful/

0

@Migomatt

Spróbuj zrobić w tej pętli coś typu var temp_i = i; i używać temp_i.

0

Dobra coś tam wykminiłem, zmieniłem Action na Action<int> i po prostu podaje position gdy wywołuję pozycję ze słownika..
Nie wiem czy to najlepsza metoda na rozwiązanie tego problemu, pewnie dałoby się lepiej i ładniej to napisać. Wydaję mi się, że trochę źle jest ta klasa podzielona na metody.. Dacie jakieś wskazówki?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SNAKE
{
    /// <summary>
    /// To create menu you need to create string [,] array to fill menu.
    /// </summary>
    /// <param name = "PossitionsListArray"> String Array with menu list</param>
    class Menu
    {
        private double HowMuchFieldsInArray;
        private string[,] MenuOptions;
        private Dictionary<int, Action<int>> OpcjeMenu = new Dictionary<int, Action<int>>();

        public Menu(string[,] PossitionsListArray)
        {
            MenuOptions = PossitionsListArray;
            HowMuchFieldsInArray = MenuOptions.Length;
            HowMuchFieldsInArray = Math.Sqrt(HowMuchFieldsInArray);


            for (int i = 0; i < HowMuchFieldsInArray; i++)
            {
                
               OpcjeMenu.Add(i, z =>
               {
                    for (int a=0; a<HowMuchFieldsInArray; a++)
                    {
                       
                      
                        if (a == z)
                        {
                            
                            Console.BackgroundColor = ConsoleColor.White;

                        }
                        else if (a-1 == z)
                        {
                            Console.BackgroundColor = ConsoleColor.Black;
                        }
                        Console.WriteLine(MenuOptions[a, 0]);
                  
                    }
         
                });
            }
        }
       


        public int CreateMenu ()
        {

            int position = 1;
            int status = 0;
            
            ConsoleKeyInfo cki;
            do
            {
                  OpcjeMenu[position](position);

                  cki = Console.ReadKey();

                switch (cki.Key)
                {


                    case ConsoleKey.UpArrow:
                        {
                            if (position == 1)
                            {
                                break;
                            }
                            else
                            {
                                position--;
                                break;
                            }

                        }

                    case ConsoleKey.DownArrow:
                        {
                            if (position == 3)
                            {
                                break;
                            }
                            else
                            {
                                position++;
                                break;
                            }

                        }
                    case ConsoleKey.Enter:
                        {
                            status = position;
                            break;
                        }

                };


                Console.Clear();

            } while (cki.Key != ConsoleKey.Enter);

            return status; //zwracam status 1- new game / 2- opcje / 3- wyjście z gry               
            }
        }


    }



1 użytkowników online, w tym zalogowanych: 0, gości: 1