Tresorknacker

    • Beta
    • Open Source

    Es gibt 38 Antworten in diesem Thema. Der letzte Beitrag () ist von Dos2k3.

      Tresorknacker

      Tresorknacker

      Name:
      Tresorknacker

      Beschreibung:
      Man hat 8 Versuche, um den Tresorcode zu erraten

      Screenshots


      Verwendete Programmiersprache(n) und IDE(s):
      Visual Basic .NET
      IDE Microsoft Visual Studio 2019


      Systemanforderungen:
      .NET Framework 4.7.2


      Download(s):
      Tresorknacker v1.6 Source Code.zip

      Lizenz/Weitergabe:
      Das Programm ist OpenSource

      Ich würde mich über Feedback freuen.

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

      Feedback kommt, sobald Du die empfohlenen Einstellungen angewendet hast (= u.a. VB6-Namespace entfernen, Option Strict On), in den Projekteigenschaften zusätzlich bei Warnungskonfiguration alle aufgelisteten Meldungen als Fehler behandelst und Dein Resourcenproblem beseitigst. Bei mir kommt der Compiler nämlich nicht mit den Hintergrundbildern zurecht. Woher kommen die eigentlich? Eigenproduktion oder Internet?
      Oh, und den Klassiker solltest Du Dir auch noch antun und beherzigen/umsetzen: Instanziierung von Forms und Aufruf von Dialogen
      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 hab jetzt mal versucht, alle empfohlenen Einstellungen umzusetzen.

      Bei mir kommt der Compiler nämlich nicht mit den Hintergrundbildern zurecht.

      Bitte erklär mir das genauer

      Woher kommen die eigentlich? Eigenproduktion oder Internet?

      Die Bilder stammen aus dem Internet
      Dateien
      Screenshots? Ich dachte dies wäre eine Vorraussetzung.
      Mfg: Gather
      Private Nachrichten bezüglich VB-Fragen werden Ignoriert!


      Hallo,

      habe mir das Spiel mal angeschaut.
      Finde das Prinzip gar nicht mal so schlecht, kann, obwohl das Prinzip recht simpel ist. zwichendurch Spaß machen. Werde es mal meinen kleinen Bruder (6Jahre) mal probieren lassen ob er es auch schon kann. :)

      Zur Bedinung kann ich sagen, dass mir als Anwender nicht klar war, wie ich eine Eingabe in der TextBox bestätige, erst nachdem ich im Programmcode geschaut habe. Hier wäre ein kleiner Hinweis auf die Entertaste ganz praktisch

      Komm ich nun aber mal zur Programmierung.
      Als erstes würde ich alle TextBox_KeyDown Events in einer Methode abfangen, ungefähr so

      VB.NET-Quellcode

      1. Private Sub txtCode_KeyDown(sender As Object, e As KeyEventArgs) Handles txtCode1.KeyDown, txtCode2.KeyDown, txtCode3.Keydown, ….
      2. '....
      3. End Sub


      Du kannst dann den TextBoxen Tags zuweisen, dass du abfragen kannst, welche TextBox geklickt wurde.
      Durch diese Methode sparst du dir viel doppelten Code und es ist auch noch ordentlicher.

      Das wars für's erste mal von mir.

      Viele Grüße
      Florian
      Vielen Dank Florian,

      ich werde das mit dem Hinweis auf die Entertaste auf jeden Fall hinzufügen. Aber wie kann ich ermitteln, bei welcher Textbox das KeyDown-Event eingetreten ist?

      MfG
      Dos2k3
      Hallo,

      Der Sender ist die TextBox, die die Methode auslöst.

      VB.NET-Quellcode

      1. Private Sub txtCode_KeyDown(sender As Object, e As KeyEventArgs) Handles txtCode1.KeyDown, txtCode2.KeyDown, txtCode3.Keydown, ….
      2. Dim aktuelleTextbox = CType(Sender, TextBox)
      3. MessageBox.Show(aktuelleTextbox.Text)
      4. '...
      5. End Sub


      Ich hoffe du hast es verstanden, wenn nicht einfach noch mal fragen.

      Viele Grüße
      Florian
      Ok danke, aber wie erhalte ich den genauen Namen der Textbox. Ich möchte quasi herausfinden, ob txtCode1 oder txtCode2 oder txtCode ... das Event ausgelöst hat.
      Könnte man den Namen nicht irgendwie aus 'Sender' oder aus 'aktuelleTextbox' auslesen ?

      MfG
      Dos2k3

      Edit: Hat sich erledigt. Habs gerade herausgefunden. Einfach auslesen über

      Quellcode

      1. aktuelleTextbox.Name


      Du willst im Grude eine If Abfrage machen, in etwa so, oder?

      VB.NET-Quellcode

      1. If gecklickteTextBox = txtCode1 Then
      2. '.....
      3. ElseIf gecklickteTextBox = txtCode2 Then
      4. '.....
      5. End If


      Dann mach es am besten so, wie ich es dir empfohlen habe:
      Weise den TextBoxen im Designer (dort wo du auch Schriftart, NAmen des Controls, usw. einstellst) einen Tag zu, für TextBox1 = 1, für TextBox2 = 2.
      Dann machst du im KeyDown Event eine Select Case (vereinfachtes If Elese) Abfrage, in etwa so:

      VB.NET-Quellcode

      1. Private Sub txtCode_KeyDown(sender As Object, e As KeyEventArgs) Handles txtCode1.KeyDown, txtCode2.KeyDown, txtCode3.Keydown, ….
      2. Dim aktuelleTextbox = CType(Sender, TextBox)
      3. MessageBox.Show(aktuelleTextbox.Text)
      4. '...
      5. If aktuelleTextbox.Tag = 1 Then 'Du hast TextBox1 den Tag 1 gegeben, deswegen findest du sie jetzt heraus
      6. .......
      7. End If
      8. End Sub


      Ich hoffe ich hab es nicht zu kompliziert erklärt :)

      Viele Grüße
      Florian
      Danke Florian, und nein, du hast es nicht zu kompliziert erklärt. ;)

      Ich hab's so ähnlich gelöst.

      Quellcode

      1. 'Aktuellen Durchgang ermitteln
      2. Select Case aktuelleTextbox.Name
      3. Case "txtCode1"
      4. Durchgang = 1
      5. aktuelles_Label = lblCode1
      6. Case "txtCode2"
      7. Durchgang = 2
      8. aktuelles_Label = lblCode2
      9. Case "txtCode3"
      10. Durchgang = 3
      11. aktuelles_Label = lblCode3
      12. Case "txtCode4"
      13. Durchgang = 4
      14. aktuelles_Label = lblCode4
      15. Case "txtCode5"
      16. Durchgang = 5
      17. aktuelles_Label = lblCode5
      18. Case "txtCode6"
      19. Durchgang = 6
      20. aktuelles_Label = lblCode6
      21. Case "txtCode7"
      22. Durchgang = 7
      23. aktuelles_Label = lblCode7
      24. Case "txtCode8"
      25. Durchgang = 8
      26. aktuelles_Label = lblCode8
      27. End Select


      MfG
      Dos2k3
      Hallo,

      ich hoffe es ist nicht schlimm, wenn ich noch weiteres Feedback gebe. :)
      Mir sind nämlich noch ein paar Kleinigkeiten aufgefallen, die ich anders machen würde:

      VB.NET-Quellcode

      1. Sub txtCode_sperren()
      2. txtCode1.Enabled = False
      3. txtCode2.Enabled = False
      4. txtCode3.Enabled = False
      5. txtCode4.Enabled = False
      6. txtCode5.Enabled = False
      7. txtCode6.Enabled = False
      8. txtCode7.Enabled = False
      9. txtCode8.Enabled = False
      10. End Sub
      11. Sub txtCode_entsperren()
      12. txtCode1.Enabled = True
      13. txtCode2.Enabled = True
      14. txtCode3.Enabled = True
      15. txtCode4.Enabled = True
      16. txtCode5.Enabled = True
      17. txtCode6.Enabled = True
      18. txtCode7.Enabled = True
      19. txtCode8.Enabled = True
      20. End Sub


      Diese zwei Methoden könnte man zusammenfassen und vereinfachen, in etwa so:

      VB.NET-Quellcode

      1. Sub txtCode_changeEnabledState(state As Boolean)
      2. txtCode1.Enabled = state
      3. txtCode2.Enabled = state
      4. txtCode3.Enabled = state
      5. txtCode4.Enabled = state
      6. txtCode5.Enabled = state
      7. txtCode6.Enabled = state
      8. txtCode7.Enabled = state
      9. txtCode8.Enabled = state
      10. End Sub


      Das Gleiche nartürlich auch bei lblCode_sperren und lblCode_entsperren.

      Des weiteren würde ich überlegen (als Übung) mit Klassen zu arbeiten.
      So würde ich zum Beispiel eine Klasse ​Code anlegen, und in diese dann die Methoden Code_generieren, usw. auslagern (hilft, gerade bei größeren Projekten der Übersicht enorm, außerdem sind Klassen bei OOP Pflicht)

      Viele Grüße
      Florian
      Im Select Case Block die Textbox Namen als String abzufragen, ist eher suboptimal, besser geht es so:

      VB.NET-Quellcode

      1. Private Sub TextBoxes_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyDown, TextBox2.KeyDown
      2. If e.KeyCode = Keys.Enter Then
      3. Dim _sender As TextBox = DirectCast(sender, TextBox)
      4. Select Case True
      5. Case _sender Is TextBox1
      6. Console.WriteLine($"{_sender.Name} : {e.KeyCode.ToString}")
      7. Case _sender Is TextBox2
      8. Console.WriteLine($"{_sender.Name} : {e.KeyCode.ToString}")
      9. End Select
      10. End If
      11. End Sub


      Alle TextBoxes aktivieren/deaktivieren geht auch mit einer Methode:

      VB.NET-Quellcode

      1. Private Sub ToggleTextBoxEnabled()
      2. For Each _control As Control In Controls
      3. If TypeOf _control Is TextBox Then
      4. _control.Enabled = Not _control.Enabled
      5. End If
      6. Next
      7. End Sub


      off topic: Bitte VB.Net Tags verwenden
      Die Anmerkung aus Post#2 hat sich. Win10 verbot mir den Zugriff auf resx-Dateien, da sie aus dem Netz kamen.

      Die letzte Box ist beim Eintritt buggy, siehe Anhang.

      @FormFollowsFunction: Dazu sollte man anmerken, dass es alle TextBoxen betreffen wird. Ok, geht hier, da sonst nix entsprechendes auf dem Form ist. Allerdings sind es MaskedTextBoxen. Kann man noch etwas kürzen:

      VB.NET-Quellcode

      1. Private Sub ToggleTextBoxEnabled()
      2. For Each MaskedTextBox In Controls.OfType(Of MaskedTextBox)
      3. MaskedTextBox.Enabled = Not MaskedTextBox.Enabled
      4. Next


      Wenn man eine MaskedTextBox und das entsprechende Label in ein UserControl packen würde und die dann zum Start dynamisch erzeugt, kann man die auch gleich in ner List speichern und dann später per For-Schleife durcharbeiten. Dann kann man sich solche Sachen wie Versuch_X und TxtCode_Y sparen.

      Bitte (nochmal) den Link aus Post#2 bzgl. Dialog-Instanziierung anschauen.
      Bilder
      • LastCode.png

        1,52 kB, 376×112, 45 mal angesehen
      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.
      Das habe ich absichtlich verschwiegen, wegen C&P-Bremse und so. :D
      Als Beispiel tuns auch TextBoxes.
      Die weitere Vereinfachung, hätte ich allerdings wissen können. [Slap my self]
      Erstmal Danke an alle für das Feedback und die Hilfe.


      Die letzte Box ist beim Eintritt buggy

      Hättest du eine Idee, woran das liegen könnte?


      Bitte (nochmal) den Link aus Post#2 bzgl. Dialog-Instanziierung anschauen

      Ich verstehe leider nicht genau, was ich umändern soll. Meinst du vielleicht, dass ich alles in dieses Schema umschreiben soll?

      Quellcode

      1. Dim dlg As New Form2
      2. dlg.ShowDialog()
      Ja, das solltest Du so umschreiben. Du hast zwar (noch) nix mit nebenläufiger Programmierung, aber im Thread Warum »Form1.Show« und Co. einem irgendwann ins Bein schießen habe ich auch erklärt, warum Menü.Show() keinen Sinn ergibt und man um sowas nen Bogen machen sollte. Ich sag nur: »Autobauplan: Fahre los!« Oder anders ausgedrückt: In nem Grundriss eines Hauses lässt sich schlecht wohnen.
      Wozu gibt' eigentlich die Subs lblCode_entsperren und txtCode_entsperren? Die werden doch nirgends benutzt.
      Du solltest für jeder Prozedurdeklaration einen Zugriffsmodifizierer setzen, damit Du weißt, von wo aus man auf die Subs/Functions zugreifen kann. Standard: Private. Also z.B. Private Function Eingabe_prüfen() As String. Dann werden dem Compiler und Dir klar: Außerhalb der Klasse ist kein Zugriff auf diese Prozedur möglich. Ohne Zugriffsmodifizierer ist alles Public, also auch von anderen Programmen aus drauf zugreifbar, wenn Dein Programm läuft.
      CType("-", Char())"-"c
      Der Microsoft.VisualBasic-Namespace ist ja noch bei Projekteigenschaften → Verweise → importierte Namespaces drin. Hinfort damit! ;)

      VB.NET-Quellcode

      1. Private Sub CmdBeginnen_Click(sender As Object, e As EventArgs) Handles cmdBeginnen.Click
      2. If SpielLäuft = False Then
      3. 'Einen zufälligen Code erhalten
      4. Code = Code_generieren()
      5. 'Speichern, dass gerade ein Spiel läuft
      6. SpielLäuft = True
      7. 'Die erste Eingabe freigeben
      8. Versuch_1()
      9. Else
      10. Exit Sub
      11. End If
      12. End Sub

      Weißt Du, was Schlimmes passiert, wenn Du den Else-Zweig mit Exit Sub weglassen würdest? Sag Du es mir.
      Schau Dir auch mal das hier an: Der Unterschied zwischen And und AndAlso/Or und OrElse
      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.