Имитация музыкального стула игры с C #, задачами и барьером - PullRequest
0 голосов
/ 24 ноября 2018

это мой первый вопрос во вселенной Stack, поэтому он может быть немного расплывчатым, но я не смог найти ответа ни в каком другом месте.

Я пытаюсь смоделировать игру на музыкальном стуле, в которойколичество игроков, количество стульев игроков-1.Музыка начинает играть, игроки вращаются по кругу, состоящему из стульев, и когда музыка останавливается, игроки садятся, тот, кто остается, проигрывает, и цикл начинается снова, пока не останется один стул, два игрока, и тот, который сидит, выигрывает.

Вот код:

private static readonly Random random = new Random();
        private static readonly object syncLock = new object();
        public static int RandomNumber(int[] auxArray)
        {
            int[] posicionesLibres = auxArray.Select((z, j) => j).Where(i => auxArray[i] == 0).OrderBy(x => Guid.NewGuid()).ToArray();
            lock (syncLock)
            {
                int auxRandom = posicionesLibres[0];
                return auxRandom;
            }
        }
        static void Main(string[] args)
        {
            Console.WriteLine("Bienvenido al Gran Juego de la Silla!");
            Console.WriteLine("Ingrese la cantidad de jugadores que van a participar: ");
            try
            {
                int cantidadJugadores = Convert.ToInt32(Console.ReadLine());

                int cantidadSillas = cantidadJugadores - 1;
                int[] sillas = new int[cantidadSillas];
                Task[] tasks = new Task[cantidadJugadores];
                Barrier barrier = new Barrier(cantidadJugadores);
                int tiempoMusica;
                int corteMusica = 0;

                Action<object> actionJugadores = (object identificador) =>
                {
                    int bandera = 0;
                    int banderaSentado = 0;

                    while (true)
                    {
                        if (bandera == 0)
                        {
                            Console.WriteLine("El Jugador {0} esta listo para jugar.", identificador);
                            bandera = 1;
                            barrier.SignalAndWait();
                        }
                        else
                        {
                            if(corteMusica == 1)
                            {
                                while (corteMusica == 1)
                                {
                                    while (banderaSentado == 0)
                                    {
                                        int posicionSilla = RandomNumber(sillas);
                                        if (Array.Exists(sillas, element => element == 0))
                                        {
                                            if (sillas[posicionSilla] == 0)
                                            {
                                                lock (sillas)
                                                {
                                                    if (sillas[posicionSilla] == 0)
                                                    {
                                                        sillas[posicionSilla] = 1;
                                                        Console.WriteLine("Me sente en la silla {0}", posicionSilla);
                                                        banderaSentado = 1;
                                                    }
                                                }
                                            }

                                        }
                                        else
                                        {
                                            banderaSentado = 1;
                                        }
                                    }
                                }
                                banderaSentado = 0;
                                barrier.SignalAndWait();
                            }  
                        }
                    }

                };

                for (int i = 0; i < cantidadJugadores; i++)
                {
                    tasks[i] = Task.Factory.StartNew(actionJugadores, (i + 1));
                }

                while (tasks.Length > 1)
                {
                    tiempoMusica = new Random().Next(3, 10);
                    Thread.Sleep(tiempoMusica * 1000);
                    Console.WriteLine("La Musica se detuvo a los {0} segundos.", tiempoMusica);
                    corteMusica = 1;
                    while(Array.Exists(sillas, element => element == 0))
                    {
                        //Espero
                    }
                    corteMusica = 0;
                    cantidadJugadores--;
                    cantidadSillas--;
                    sillas = new int[cantidadSillas];
                    barrier.RemoveParticipant();
                    //Matar al looser
                }
            }
            catch (AggregateException ae)
            {
                foreach(var ex in ae.InnerExceptions)
                    Console.WriteLine(ex.Message);
            }
            Console.ReadLine();
        }
}

Самая важная проблема заключается в том, что во втором и последующих раундах я получаю игроков, которые уже проиграли, или, возможно, один и тот же игрок садится дважды;кроме некоторых случайных проблем переполнения.

Справка?

...