Więc chcę móc analizować i oceniać "wyrażenia kostki" w języku C#. Wyrażenie kostki jest zdefiniowane w następujący sposób:Wyrażenia kostki parsowania (np. 3d6 + 5) w języku C#: od czego zacząć?
<expr> := <expr> + <expr>
| <expr> - <expr>
| [<number>]d(<number>|%)
| <number>
<number> := positive integer
Tak np. d6+20-2d3
będzie mogła i powinna ocenić jako
rand.Next(1, 7) + 20 - (rand.Next(1, 4) + rand.Next(1, 4))
także d%
powinna być równoważna d100
.
Wiem, że mogę zhakować razem jakieś rozwiązanie, ale wiem też, że wydaje się to bardzo typowym problemem komputerowo-naukowym, więc musi być jakieś super-eleganckie rozwiązanie, które powinienem zbadać.
Chciałbym wynik mojego parsowania mieć te funkcje:
- powinienem być w stanie do wyjścia znormalizowaną formą wypowiedzi; Najpierw myślę o kościach, posortowane według rozmiaru kości i zawsze z prefiksem. Np. powyższa próbka stanie się
1d6-2d3+20
. Również wszelkie wystąpieniad%
staną sięd100
w znormalizowanej postaci. - Powinienem być w stanie ocenić wyrażenie w-woli, tocząc różne liczby losowe za każdym razem.
- Powinienem być w stanie ocenić wyrażenie ze zmaksymalizowanymi wszystkimi rzutami kości, np. próbka powyżej dałaby (deterministycznie)
1*6+20+2*3 = 32
.
Wiem, że to jest dokładnie taki typ rzeczy, w którym Haskell i prawdopodobnie inne języki funkcjonalne byłyby świetne, ale chciałbym pozostać w C#, jeśli to możliwe.
Moje początkowe myśli mają tendencję do rekurencji, list, a może niektórych LINQ, ale znowu, jeśli spróbuję bez wskazówek od ludzi, którzy znają się na rzeczy, jestem pewien, że skończyłoby się to nieeleganckim bałaganem.
Inną taktyką, która może zadziałać, byłby jakiś początkowy zastępczy łańcuch znaków zastępujący wyrażenia kostki w wywołaniach rand.Next
, a następnie ocena lub kompilacja w locie ... czy to faktycznie zadziałałoby? Jak mogę uniknąć tworzenia nowego obiektu za każdym razem?
random.Next jest kompletna i to drugi parametr jest wyłączna. http://msdn.microsoft.com/en-us/library/2dx6wyd4%28VS.95%29.aspx – Domenic
Wystarczająco fair :) – annakata
Chyba masz na myśli: rand.Next (1, 7) + 20 - (rand. Dalej (1, 4) + rand. Dalej (1, 4)) –