Exemplo n.º 1
0
        /// <summary>
        /// Metoda wykonująca "zakręcenie" bębnami maszyny.
        /// Po zakończeniu aktualizowana jest ilość wygranych jeśli jest taka potrzeba oraz liczba punktów.
        ///
        /// Rzuca wyjątki jeśli jest niewystarczająca liczba kredytów lub generator wyników źle działa.
        /// </summary>
        /// <returns>Kolekcja historia kolejnych "głównych" elementów każego z węzłów wraz z wartością wygranej jeśli nastąpiła</returns>
        public (IEnumerable <IEnumerable <T> > reelsSpinHistory, uint?nWinValue) Spin()
        {
            //Zapamiętujemy ustawioną stawkę. Zapamiętujemy, żeby mieć oryginalną wartość jak ktoś potem by ją zmienił
            uint nSpinBid = Bid;

            if (this.Credits < nSpinBid)
            {
                throw new InvalidOperationException("Insufficient Credits.");
            }

            List <IEnumerable <T> > spinResult = new List <IEnumerable <T> >();
            List <T> currentCombination        = new List <T>();

            IEnumerable <T> nextResult = m_resultGenerator.GetNextResult();

            //Nie powinno być tak, że ktoś dostarcza źle skonstruowany generator. Nie obsługujemy.
            if (nextResult == null || nextResult.Count() != m_reels.Count())
            {
                throw new InvalidOperationException("Result Generator didn't return number values exactly to number of reels.");
            }

            //Każdy z wyników powinien być osiągalny na bębnie. Nie obsługujemy błędów.
            bool bAreAllResultsPossible = true;

            for (int i = 0; i < m_reels.Count(); i++)
            {
                //Upewniamy się,  że możemy utworzyć dany wynik
                if (!m_reels.ElementAt(i).CheckIfExist(nextResult.ElementAt(i)))
                {
                    bAreAllResultsPossible = false;
                }
            }

            if (!bAreAllResultsPossible)
            {
                throw new InvalidOperationException("Returned result is nott possible to set.");
            }

            for (int i = 0; i < m_reels.Count(); i++)
            {
                IEnumerable <T> spinHistory = m_reels.ElementAt(i).SetNextValue(nextResult.ElementAt(i));
                spinResult.Add(spinHistory);

                //Zapamiętujemy też wynik obecnego położenia. Obecne położenie jest to ostatni element z historii.
                currentCombination.Add(spinHistory.LastOrDefault());
            }

            //Jak wszystko poszło, to odejmujemy od kredytów postawioną stawkę
            Credits -= nSpinBid;

            //Pobieramy wygraną dla danego ustawienia (będzie null przy braku wygranej)
            //Zakładamy że konieczne jest dokładnie takie ustawienie jak mamy.
            //Wersja bardziej rozszerzona to klasa wyników, do której przekazywalibyśmy obecny wynik i ona sama by zwracała wygraną.
            uint?nWin = m_winingTable.Where(kv => Enumerable.SequenceEqual(kv.Key, currentCombination)).Select(kv => kv.Value).Cast <uint?>().FirstOrDefault();

            //Jeżeli mamy wygraną, to mnożymy jej wartość razy stawkę i dodajemy do punktów oraz zwiększamy ilość wygranych
            if (nWin.HasValue)
            {
                nWin     = nWin.Value * nSpinBid;
                Credits += nWin.Value;
                Wins++;
            }

            return(reelsSpinHistory : spinResult, nWin);
        }