Kniffel in der Konsole

  • VB.NET
  • .NET 4.5

Es gibt 16 Antworten in diesem Thema. Der letzte Beitrag () ist von Visual_Prog.

    Kniffel in der Konsole

    Moinsen,
    und zwar kennt doch jeder das Würfelspiel Kniffel.
    Bin jetzt dabei das en der Konsole zu programmieren, jedoch nur den oberen Teil des Kniffelblattes (Augenzahlen der Zahlen 1-6).
    In der Konsole reizt es mich einfach mehr als in einer Windows-Form.

    Hinweis : Der Einfachheit halber entscheidet man sich in meinem Programmchen schon vor dem zweiten Wurf für eine Zahl.
    Das heißt, man kann nicht biem zweiten und drittel Wurf eine unterschiedliche Zahl auswählen, sondern wählt dann immer die gleich. (Es wären mir erstmal einfach zu viele If-Abzweigungen).
    - außerdem bin ich erst bei den zahlen 1 und 2, das heißt 3-6 sind noch nicht funktionsfähig.

    Mein Problem: geht es kürzer? vielliecht interessiert sich Jemand für das Projektchen und kann Abkürzungshinweise geben. Danke LG


    VB.NET-Quellcode

    1. Module Module1
    2. 'erstemalwürfeln
    3. Public zufall As New Random
    4. Public ziffer As Integer
    5. Public ZL As New List(Of Integer)
    6. Public anzahlaneiner As Integer = 0
    7. Public anzahlanzweier As Integer = 0
    8. 'zweitesmalwürfeln
    9. Public auswahl As Integer
    10. Public ziffer02 As Integer
    11. Public anzahlaneiner02 As Integer = 0
    12. Public anzahlanzweier02 As Integer = 0
    13. 'drittesmalwürfeln
    14. Public anzahlaneiner03 As Integer = 0
    15. Public anzahlanzweier03 As Integer = 0
    16. Public Sub Erstesmalwürfeln()
    17. Console.WriteLine("Bitte Würfeln Sie jetzt: ")
    18. For i = 0 To 4
    19. ziffer = zufall.Next(1, 7)
    20. ZL.Add(ziffer)
    21. Console.Write(ziffer)
    22. Console.Write(" ")
    23. Next
    24. 'anzahl an zahlen festlegen
    25. For Each element As Integer In ZL
    26. Select Case element
    27. Case 1
    28. anzahlaneiner += 1
    29. Case 2
    30. anzahlanzweier += 1
    31. End Select
    32. Next
    33. Console.WriteLine()
    34. End Sub
    35. Public Sub zweitesmalwürfeln()
    36. ZL.Clear()
    37. Console.WriteLine("Bitte wählen Sie ihre Zahl aus:")
    38. auswahl = CInt(Console.ReadLine())
    39. If auswahl = 1 Then
    40. For i = 0 To 4 - anzahlaneiner
    41. ziffer02 = zufall.Next(1, 7)
    42. ZL.Add(ziffer02)
    43. Console.Write(ziffer02)
    44. Console.Write(" ")
    45. Next
    46. ElseIf auswahl = 2 Then
    47. For i = 0 To 4 - anzahlanzweier
    48. ziffer02 = zufall.Next(1, 7)
    49. ZL.Add(ziffer02)
    50. Console.Write(ziffer02)
    51. Console.Write(" ")
    52. Next
    53. End If
    54. 'anzahl an zahlen festlegen
    55. For Each element As Integer In ZL
    56. Select Case element
    57. Case 1
    58. anzahlaneiner02 += 1
    59. Case 2
    60. anzahlanzweier02 += 1
    61. End Select
    62. Next
    63. Console.WriteLine()
    64. End Sub
    65. Public Sub drittesmalwürfeln()
    66. ZL.Clear()
    67. Console.WriteLine("Bitte wählen Sie ihre Zahl aus:")
    68. auswahl = CInt(Console.ReadLine())
    69. If auswahl = 1 Then
    70. For i = 0 To 4 - anzahlaneiner - anzahlaneiner02
    71. ziffer02 = zufall.Next(1, 7)
    72. ZL.Add(ziffer02)
    73. Console.Write(ziffer02)
    74. Console.Write(" ")
    75. Next
    76. ElseIf auswahl = 2 Then
    77. For i = 0 To 4 - anzahlanzweier - anzahlanzweier02
    78. ziffer02 = zufall.Next(1, 7)
    79. ZL.Add(ziffer02)
    80. Console.Write(ziffer02)
    81. Console.Write(" ")
    82. Next
    83. End If
    84. 'anzahl an zahlen festlegen
    85. For Each element As Integer In ZL
    86. Select Case element
    87. Case 1
    88. anzahlaneiner03 += 1
    89. Case 2
    90. anzahlanzweier03 += 1
    91. End Select
    92. Next
    93. Console.WriteLine()
    94. End Sub
    95. Public Sub ergebnis()
    96. If auswahl = 1 Then
    97. Console.WriteLine("Sie haben die 1 so oft gewürfelt: " & anzahlaneiner + anzahlaneiner02 + anzahlaneiner03 & " dabei haben sie die Augenzahl " & _
    98. anzahlaneiner * 1 + anzahlaneiner02 * 1 + anzahlaneiner03 * 1 & " erreicht.")
    99. ElseIf auswahl = 2 Then
    100. Console.WriteLine("Sie haben die 2 so oft gewürfelt: " & anzahlanzweier + anzahlanzweier02 + anzahlanzweier03 & " dabei haben sie die Augenzahl " & _
    101. anzahlanzweier * 2 + anzahlanzweier02 * 2 + anzahlanzweier03 * 2 & " erreicht.")
    102. End If
    103. End Sub
    104. Sub main()
    105. Erstesmalwürfeln()
    106. zweitesmalwürfeln()
    107. drittesmalwürfeln()
    108. ergebnis()
    109. Console.readline()
    110. End Sub
    111. End Module

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Visual_Prog“ ()

    Sobald Du sowas glaubst zu brauchen: anzahlaneiner, anzahlanzweier, anzahlaneiner02, anzahlanzweier02, anzahlaneiner03, anzahlanzweier03, liegst Du schon daneben. Arbeite mit Listen oder Feldern. Dann wird auch der Umgang mit den Würfel-Subs einfacher, weil Du nur eine brauchst.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    habe diese einzelnen Integer durch Listen ersetzt und das ganze in einer Sub gepackt, wo auch ein Loop drinne ist zur Verkürzung(Zeile 47).
    Soweit kann ich dann die anderen Zahlen auffüllen oder kann man noch was kürzen?
    danke lg

    VB.NET-Quellcode

    1. Module Module1
    2. 'allgemeine variablen
    3. Public zähler As Integer = 0
    4. 'erstemalwürfeln
    5. Public zufall As New Random
    6. Public ziffer As Integer
    7. Public ZL As New List(Of Integer)
    8. Public anzahlaneinerliste As New List(Of Integer)
    9. 'zweitesmalwürfeln
    10. Public auswahl As Integer
    11. Public ziffer02 As Integer
    12. Public anzahlanzweierliste As New List(Of Integer)
    13. 'SUb würfeln
    14. Public Sub würfeln()
    15. Console.WriteLine("Bitte Würfeln Sie jetzt: ")
    16. For i = 0 To 4
    17. ziffer = zufall.Next(1, 7)
    18. ZL.Add(ziffer)
    19. Console.Write(ziffer)
    20. Console.Write(" ")
    21. Next
    22. 'anzahl an zahlen festlegen
    23. For Each element As Integer In ZL
    24. Select Case element
    25. Case 1
    26. anzahlaneinerliste.Add(1)
    27. Case 2
    28. anzahlanzweierliste.Add(2)
    29. End Select
    30. Next
    31. Do
    32. Console.WriteLine()
    33. ZL.Clear()
    34. Console.WriteLine("Bitte wählen Sie ihre Zahl aus:")
    35. auswahl = CInt(Console.ReadLine())
    36. If auswahl = 1 Then
    37. For i = 0 To 4 - anzahlaneinerliste.Count
    38. ziffer02 = zufall.Next(1, 7)
    39. ZL.Add(ziffer02)
    40. Console.Write(ziffer02)
    41. Console.Write(" ")
    42. Next
    43. ElseIf auswahl = 2 Then
    44. For i = 0 To 4 - anzahlanzweierliste.Count
    45. ziffer02 = zufall.Next(1, 7)
    46. ZL.Add(ziffer02)
    47. Console.Write(ziffer02)
    48. Console.Write(" ")
    49. Next
    50. End If
    51. 'anzahl an zahlen festlegen
    52. For Each element As Integer In ZL
    53. Select Case element
    54. Case 1
    55. anzahlaneinerliste.Add(1)
    56. Case 2
    57. anzahlanzweierliste.Add(2)
    58. End Select
    59. Next
    60. zähler += 1
    61. Loop Until zähler = 2
    62. Console.WriteLine()
    63. End Sub
    64. Public Sub ergebnis()
    65. If auswahl = 1 Then
    66. Console.WriteLine("Sie haben die 1 so oft gewürfelt: " & anzahlaneinerliste.Count & " dabei haben sie die Augenzahl " & _
    67. anzahlaneinerliste.Count * 1 & " erreicht.")
    68. ElseIf auswahl = 2 Then
    69. Console.WriteLine("Sie haben die 2 so oft gewürfelt: " & anzahlanzweierliste.Count & " dabei haben sie die Augenzahl " & _
    70. anzahlanzweierliste.Count * 2 & " erreicht.")
    71. End If
    72. End Sub
    73. Sub main()
    74. würfeln()
    75. ergebnis()
    76. Console.ReadLine()
    77. End Sub
    78. End Module

    Siehe Post#1:

    Visual_Prog schrieb:

    außerdem bin ich erst bei den zahlen 1 und 2, das heißt 3-6 sind noch nicht funktionsfähig.


    ##########

    Auch wenn ich mich noch nicht komplett mit dem Code beschäftigt habe, würde ich da einen Gesamt-Gegenvorschlag entwickeln. Nur weiß ich nicht, ob das zielführend wäre, @Visual_Prog
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()

    ok, dann also zur Frage, wie kürzer: Schau, welcher Code immer gleich aussieht - das kann man in eine Methode verlagern. Zb dahier:

    VB.NET-Quellcode

    1. For i = 0 To 4 - anzahlaneinerliste.Count
    2. ziffer02 = zufall.Next(1, 7)
    3. ZL.Add(ziffer02)
    4. Console.Write(ziffer02)
    5. Console.Write(" ")
    6. Next
    ist dasselbe wie dem hier:

    VB.NET-Quellcode

    1. For i = 0 To 4 - anzahlanzweierliste.Count
    2. ziffer02 = zufall.Next(1, 7)
    3. ZL.Add(ziffer02)
    4. Console.Write(ziffer02)
    5. Console.Write(" ")
    6. Next
    das kann in eine Methode, dann schrumpft sich das ganz ungemein.
    Auch in der Ergebnissub ist Redundanz: If auswahl = 1 … Sie haben die 1 so oft gewürfelt … anzahlaneinerliste.Count * 1 (explizit ohne CodeTags)
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    :huh: Ich dächt, Dir wär Konsole lieber. Ist doch auch umsetzbar. Ich glaube nicht, dass Dir WinForms da nen unschlagbaren Vorteil bietet. Es ist immer wieder die Datenmodellbasis, die passen muss.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    Ich weiss auch nicht, wie unsere Vorschläge in Richtung Winforms führen, aber die entscheidung ist so oder so richtig. :thumbsup:
    Ein Konsole-Programm ist nicht interaktiv, dassis was für einen Dienst, aber nix, womit ein Mensch als Benutzer sich rumärgern möchte.
    Konsole-Programmierung ist ganz ganz stark prozedural orientiert.
    Man kann da keine "wirkliche" Programmierung lernen, objekt- und event- orientiert.
    Mit Konsole ins Programmieren einsteigen sehe ich sehr fragwürdig, weil man da den prozeduralen Stil trainiert und sich angewöhnt.
    Und wie mit Strict On und dem MVB-Namespace vermute ich, dass diese Gewohnheiten einem massiv im Wege stehen, wenn man seine Denke auf objekt- und event- orientiert umstellen muss.



    Aber schade - ich hätte gerne noch den TE beim Lernschritt begleitet, wie man eine Reihe von Anweisungen, die sechs mal auftritt, in eine parametrisierte Methode überführt (post#7).
    Sodass die Anweisungen nur noch einmal vorkommen - in der Methode - welche dann sechs mal aufgerufen wird.
    Dieses Konzept sauberer Programmierung (Fachwort: "strukturierte Programmierung") ist im prozeduralen Paradigma ebenso unerlässlich wie im event-orientierten.
    Und wäre gut aufzuzeigen gewesen.

    Jetzt läuft er davor quasi davon und fängt erstmal was ganz neues an.
    :huh: Deine Konsoleneinwände kann ich bzgl. Objektorientierung und EventHandling nicht ganz nachvollziehen. Klar, im Gegensatz zu nem GUI, welches im Hintergrund in seiner MessageLoop festhängt, hängt ne Konsolenanwendung in ner klassischen Do- oder While-Schleife fest und wartet auf die nächste Eingabe (und bekommt in der Zeit nix anderes mit). Bei nem Kniffelspiel ist das doch kein Beinbruch. Da wartet man doch auch in der Realität, dass man würfelt und sich entscheidet. Objektorientierung seh ich jetzt nicht gerade als GUI-spezifisch bzw. ich seh da nicht das Konsolenproblem. Und Events: auch möglich/umsetzbar. Sogar m.E. auch sinnvoll umsetzbar, siehe MSDN-Beispiel 1. Die Counter-Klasse weiß nicht, was bei Limitüberschreitung passiert, darum kümmert sich die Main-Sub selbst.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.
    Ja, haste recht.
    Objektorientierung **kann** man auch in einer Konsole machen - nur ist mir noch nie jemals untergekommen, dass das auch mal gemacht würde.
    Ebenso Event-Orientierung: **Möglich** ist das - macht blos niemand (vmtl. weils meist nicht sinnvoll ist, s.u.).

    Das von dir angeführte Msdn-Beispiel kann man ebensogut auch als unsinnig betrachten:
    Die verkünsteln sich da mit 50Zeilen, 2 Klassen, 1 Event und 5 Methoden, um was zu bewirken, was ein normaler Mensch prozedural(!) in 10 zeilen abgehandelt hat.
    Bei denen man dann auch sofort durchblickt.
    Aber klar, die wollen da ein Event zeigen - nicht ein Problem sinnvoll lösen.
    Also um Event zu zeigen ist das Beispiel brauchbar, als Konsole-Demo ists eher ein Anti-Beispiel.



    Dass Kniffel für Konsole geeignet sei ziehe ich in Zweifel. Hab jetzt spasseshalber VisualProgs Experiment bei mir zum laufen gebracht, und erkenne das Spiel Kniffel wie ich es kenne garnet wieder.
    Ich hab auch Mühe, mir einen Console-Workflow auszudenken, der das Spiel abbilden würde.

    In WinForms fällt mir das viel leichter: Eine CheckedListbox oder ein DGV zeigt den geworfenen Wurf an, und mit der Maus wählt man die Einträge aus, die man aus der WürfelMenge fortnehmen möchte, dann klickst man "würfeln", und der nächste Wurf wird angezeigt.

    Ok - dass ichs nicht wiedererkenne liegt daran, dass es nur für 1 und 2 funktioniert, und dass man nur Pasch-Ziffern "rausnehmen" kann.
    Hier zeigt sich aber die Konsole-Beschränkung: nämlich das mit nur PaschZiffern rausnehmen hat er vmtl. so gemacht, weil ein Rausnehmen beliebiger Würfel in Konsole lästig einzugeben wäre.
    Und der Programmier-Aufwand zum Absichern gegen Fehl-Eingaben würde blitzgeschwind ins Groteske wachsen. (Waren die Würfel, die er rausnimmt denn überhaupt im Wurf drinne?)
    Was wiederum auf WinForms hinführt: Eine CheckedListbox - da kannste nix abwählen, was nicht drinne ist.
    Also selbst für einen Simpel wie Kniffel ist Konsole nicht interaktiv genug.

    Jo, vlt. haste recht, dasses nicht an Objektorientierung oder Events liegt, dass Konsole für nix zu gebrauchen ist, sondern wirklich nur an mangelnde Interaktivität.
    Wennde mit KonsoleProgrammierung gestraft bist, dann musste an der Stelle - Interaktion, Benutzerführung, Eingabe-Validierung - einen Riesen-Aufwand treiben - vertane Zeit und Hirnschmalz.
    Besser hätteste ein paar Controls aufs Form geschmissen und mit rumgespielt, und dabei was gelernt, was auch zu gebrauchen ist.

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Anbei mal der Erstentwurf meiner Konsolen-Kniffel-Variante. Ohne Events, aber mit Interaktivität. Zumindest, was ich mir drunter vorstelle. Nachdem man das Spiel gestartet hat, wird das erste Würfelergebnis angezeigt. Dann kann man mit der Oben-/Unten-Pfeiltaste ein Einzelwürfelergebnis auswählen, welches man behalten will und drückt Space, um die Auswahl zu bestätigen (also Mehrfachauswahl). Wenn man alle interessanten Würfel ausgewählt hat, drückt man Enter. Dann entscheidet man, welche Würfelergebnisse man verwerfen und somit die Würfel wieder ins Spiel bringen will. Am Ende des Zugs (also nach 3x Würfeln oder nachdem man sich für alle 5 Würfel entschieden hat) werden die punkterelevanten Ergebnisse angezeigt und man muss sich entscheiden, wohin man das Würfelergebnis auf seine Spielergebniskarte (auch mit oben/unten und dann Enter, also Einzelauswahl) schreiben will.
    Dateien
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.

    Neu

    @VaporiZed Moinsen ich würds mir sehr gern anschauen aber ich krieg das Ding nicht geöffnet.

    Runterladen und entpacken klappt.

    Habe Visual Studio 2013 und von net.framework habe ich mir die version 4.71 und 4.8 geladen weil ich dachte es liegt daran aber anscheinend nicht =/

    Ich kanns im Visual Studio öffnen aber dann wird einfach nichts angezeigt.

    Neu

    Habe VS2019 CE. Könnte daran liegen. Ansonsten hatte ich .NET FW 4.7.2 eingestellt. Versuch mal in den Projekteigenschaften das Framework auf 4.8 einzustellen.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Häufig von mir verwendete Abkürzungen: CEs = control elements (Labels, Buttons, DGVs, ...) und tDS (typisiertes DataSet)
    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht in den Spekulatiusmodus gehen.

    Neu

    ok anscheinend unterstützt Visual Studio 2013 keine höhere versionen von net framework als 4.5, denn ich habe die 4.72 und 4.8 installiert, aber kann man in den Einstellungen nicht annehmen. Brauche wohl ein neuer VS.

    Immerhin kann ich den Code jetzt lesen. Danke fürs teilen!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Visual_Prog“ ()