Kniffel Code-Stil und Lösungswege

  • VB.NET

Es gibt 3 Antworten in diesem Thema. Der letzte Beitrag () ist von Blutlust.

    Kniffel Code-Stil und Lösungswege

    Hallo VB-Paradise Community,

    Ich will mich mit meinem 1. Post mal kurz vorstellen bevor ich zu meinem Anliegen komme. Ich heiße Steve bin 29 Jahre alt und möchte mich auf meine "alten" Tage noch mal als Hobby mit dem programmieren beschäftigen. Nun habe ich vor gut einem Monat mich dazu entschieden Visual Basic zu lernen.

    Nach den ersten obligatorischen Radioplayer und Browser habe ich mich dazu entschlossen ein Kniffel Spiel zu programmieren.


    Es funktioniert auch soweit alles, jedoch bin ich mit meinen Lösungswegen und dem Code-Stil noch nicht zufrieden.

    Der Lösungsweg zum berechnen der kleinen Straße sind bei mir 15 Schleifen. Ich speichere die 5 Würfel in einem Array.
    Dieser wird sortiert. Jetzt kann ja eine kleine Straße aus 3 Möglichkeiten bestehen.
    • 1, 2, 3, 4, X, X
    • X, 2, 3, 4, 5, X,
    • X, X, 3, 4, 5, 6,
    (bzw. auch doppelten Zahlen...) diese 3 Möglichkeiten a 5 Würfel sind 15 Wege auf dem man eine kleine Straße bekommen kann.
    Diese 15 Wege frage ich mit Contains ab.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. If Wurf(0).Contains(1) Or Wurf(1).Contains(1) Then '1
    2. If Wurf(1).Contains(2) Or Wurf(2).Contains(2) Then '2
    3. If Wurf(2).Contains(3) Or Wurf(3).Contains(3) Then '3
    4. If Wurf(3).Contains(4) Or Wurf(4).Contains(4) Then '4
    5. usw...

    Es gibt bestimmt eine elegantere Lösung! Jedoch reicht mein wissen da noch nicht aus.

    Für Tips und Tricks wäre ich dankbar.

    MfG Steve
    Ich denke und denke und denke , aber komme nicht ganz weiter.
    Ich würde dir empfelen ne Schleife zu bauen die die würfel der größe nach sortiert und doppelte rauslöschst.
    Dann ne schleife mit ner if-abfrage die die zahlen durchgehen.

    VB.NET-Quellcode

    1. For i As Integer = 0 To 5
    2. If Sortiert(i) = Sortiert(i+1) +1 then
    3. counter = counter + 1
    4. else
    5. counter = 0
    6. Next i


    Außerdem brauchst du noch nen counter wie viele in folge zueinander passen und wenn bei der if abfrage false rauskommt wird der counter auf 0 gesetzt.
    Zu beachten ist das die schleife sofort stoppen muss , wenn 4 erreicht ist. (ach und so kann man auch die große straße abfragen.

    So habe ich mir das gerade ausgedacht , ob das ne gute lösung ist weis ich nicht aber es ist aufjedenfall um einiges Kürzer.
    Außerdem habe ich mir das gerade aus den Fingerngezogen und bin mir nicht sicher ob der Code da Funktioniert. Aber ein schönes Denkspiel!!
    Du solltest versuchen, die möglichen Ergebnisse "formal" zu beschreiben,

    zb:

    VB.NET-Quellcode

    1. Public Class KniffelTool
    2. Private Shared rgen As New Random
    3. Public Shared Function ThrowDice() As List(Of Integer)
    4. Dim l As List(Of Integer) = New List(Of Integer)
    5. For i = 1 To 5
    6. l.Add(rgen.Next(1, 7))
    7. Next
    8. l.Sort()
    9. Return l
    10. End Function
    11. Public Shared Sub Analyse(ByVal l As List(Of Integer))
    12. Dim DistinctValues As IEnumerable(Of Integer) = From i As Integer In l Select i Distinct Order By i
    13. Dim GroupedValues = From i As Integer In l Group i By i Into Anzahl = Count() Order By i
    14. Dim s As String = String.Empty
    15. For i As Integer = 0 To 4
    16. s &= l(i) & " "
    17. Next
    18. Debug.Print(s)
    19. If DistinctValues.Count = 5 Then
    20. ' große Strasse?
    21. If DistinctValues(4) - DistinctValues(0) = 4 Then
    22. Debug.Print("Große Strasse")
    23. Else
    24. Debug.Print("KEINE Große Strasse")
    25. End If
    26. ' kann auch kleine S sein
    27. If DistinctValues(4) - DistinctValues(1) = 3 OrElse DistinctValues(3) - DistinctValues(0) = 3 Then
    28. Debug.Print("Kleine Strasse")
    29. Else
    30. Debug.Print("KEINE Kleine Strasse")
    31. End If
    32. End If
    33. If DistinctValues.Count = 4 Then
    34. ' Kleine Strasse?
    35. If DistinctValues(3) - DistinctValues(0) = 3 OrElse DistinctValues(4) - DistinctValues(1) = 3 Then
    36. Debug.Print("Kleine Strasse")
    37. Else
    38. Debug.Print("KEINE Kleine Strasse")
    39. End If
    40. End If
    41. If DistinctValues.Count = 3 Then
    42. 'evtl Dreierpasch
    43. Dim r = From gg In GroupedValues Where gg.Anzahl > 2 Select gg.i
    44. If r.Count > 0 Then
    45. Debug.Print("Dreierpasch")
    46. End If
    47. End If
    48. If DistinctValues.Count = 2 Then
    49. If GroupedValues(0).Anzahl = 3 Or GroupedValues(1).Anzahl = 3 Then
    50. Debug.Print("Full House")
    51. ' außerdem natürlich noch ein Dreierpasch!
    52. Else
    53. Debug.Print("KEIN Full House, aber Viererpasch!")
    54. End If
    55. End If
    56. If DistinctValues.Count = 1 Then
    57. ' Kniffel! Dreierpasch, Viererpasch!
    58. Debug.Print("Bullseye!!!")
    59. End If
    60. End Sub
    61. End Class


    Erklärung:
    zuerstmal werden zwei sortierte Listen erzeugt.
    Die eine enthält alle Augen OHNE doppelte (3,1,2,2,1 wird zu 1,2,3) und die andere enthält zusätzlich die jeweiligen Anzahlen (3,1,2,2,1 wird zu 1(2), 2(2), 3(1))
    Jetzt weiß man dass eine kleine Strasse MINDESTENS 4 unterschiedliche augen braucht.
    Wenn 4 unterschiedliche: 1,2,3,4 oder 2,3,4,5 oder 3,4,5,6 -> Die Differenz des letzten und des ersten MUSS 3 sein!
    Wenn 5 unterschiedliche: entweder sind die ersten 4 Augen eine kleine Strasse, oder die zweiten 4. Also suche ich wieder die Differenz von 3 zwischen dem 1. und 4. oder dem 2. und 5.!
    Wenn es 5 unterschiedliche Augen sind, muss die Differenz bei einer GROSSEN Strasse 4 sein!
    Ein FullHouse erkenne ich daran, dass es GENAU 2 unterschiedliche Augen gibt und das ein Wert genau 3 mal vorkommt (der andere Wert kommt dann zwei Mal vor). Alternativ kann ein wert 4 mal vorkommen, dann ist es ein Viererpasch.

    Analog kann man alle anderen Möglichkeiten prüfen

    NACHTRAG: Hier gibts auch noch ein schönes Bsp. für Kniffel/Yahtzee mit LINQ:
    c-sharpcorner.com/UploadFile/m…010520AM/YahtzeeLINQ.aspx

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „picoflop“ ()