Spiel (Memory)

  • VB.NET

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von Mad Andy.

    Hi
    Ich hab da ein Problem: Ich möchte ein Kartenspiel programmieren. Mein Problem ist: Wie kann man es sagen, dass jeweils nur 2 Karten gleich sein dürfen und es bei jedem Neustart des Spiels, die Karten anders verteilt sind (halt wie bei Memory). Ich hab dies zwar probiert, irgendwie mit einem Random hinzubekommen, aber das geht irgendwie nicht. Ich hoffe, ihr könnt mir helfen,
    Gruß Michi
    Angenommen es sind 4x4 felder, so sind es 16 karten --> 8 unterschiedliche
    dann machst du einen Array mit (0 to 3, 0 to 3) und eine schleife von 1 bis 8, schiebst bei jedem Schleifendurchlauf i 2x an eine zufällige X und Y Position im Array.
    Anschließend zeichnest du nurnoch den Array auf die Form.

    Das mit dem Zufall geht so:

    VB.NET-Quellcode

    1. Randomize() 'einmal VOR der schleife aufrufen; initialisiert neue Zufallszahlen
    2. Dim value As Integer = CInt(Int(3 * Rnd())) 'Zufallszahl zwischen 0 und 3



    mfG Andy

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

    Könntest du mir das mit den Array genauer erklären?, irgendwie versteh ich das nicht ganz. Also ich hab es jetzt so

    VB.NET-Quellcode

    1. Private Sub Array()
    2. For z = 0 To 3
    3. t(z) = 16
    4. Next
    5. For z = 1 To 8
    6. 'weiß nicht ob das bis hier hin richtig ist.
    7. Next
    8. End Sub

    Wie meinst du denn das mit dem Schleifendurchlauf 2x an eine zufällige x und Y Position im Array?

    gruß Michi
    Hi!

    Ein Array ist eine Liste von Werten.
    Wenn der Array 2-Dimensional ist, kannst du dir das in etwa wie eine (Excel-) Tabelle vorstellen.

    Du hast also eine Gitter/Tabelle von 4x4 feldern und jede Karte kommt doppelt drin vor an zufälligen Positionen. Das heißt wir brauchen 2x (sind ja 2 Karten pro Typ) 2 Zufallszahlen (x- und y-Wert).

    VB.NET-Quellcode

    1. Dim KartenArray() as Integer 'Leeres Kartengitter definieren
    2. Private Sub KartenLegen()
    3. Dim i as Integer, j as Integer 'Zählervariablen
    4. Dim x as Integer, y as Integer 'Hier werden der x- und y-Wert zwischengespeichert
    5. Redim KartenArray(3, 3) 'Karten Array löschen und Größe zuweise (0 bis 3|0 bis 3)
    6. Randomize() 'Zufallsreihe generieren
    7. For i = 1 to 8 '8 Unterschiedliche Karten
    8. For j = 1 to 2 '2 karten von jedem Typen
    9. Do 'Schleife: Zufallszahl generieren, bis ein leeres Feld gefunden wird
    10. x = cInt(Int(3* Rnd())) 'Erzeugt eine Integer-Zufallszahl zwischen 0 und 3
    11. y = cInt(Int(3* Rnd())) 'und noch eine für y
    12. Loop Until KartenArray(x, y) = 0 '0 ist der Startwert eines Integers, Sobald eine Karte drin ist, ist der wert 1...8
    13. KartenArray(x, y) = i 'Karte an die ermittelte Position speichern.
    14. Next j
    15. Next i
    16. End Sub
    17. 'Hier machen wir einfach mal eine Ausgabe in eine Textbox um zu sehen, obs funktioniert.
    18. 'Eigenschaft .MultiLine auf true setzen!
    19. Private Sub KartenZeichnen()
    20. Dim x as Integer, y as Integer 'Gitterzählervariablen
    21. TextBox1.Text = ""
    22. For y = 0 to 3
    23. For x = 0 to 3
    24. TextBox1.Text = TextBox1.Text & KartenArray(x, y) & vbTab 'nachste Spalte
    25. Next x
    26. TextBox1.Text = TextBox1.Text & vbCrLf 'nächste Zeile
    27. Next y
    28. End Sub
    Vielen Dank Mad Andy für den code!
    Nur leider funktioniert das Beispiel nicht richtig --(
    Bei Zeile 7, also bei

    VB.NET-Quellcode

    1. KartenArray(3, 3)
    kommt: "Redim kann die Anzahl der Dimensionen nicht ändern".
    Und (warscheinlich ein Folgefehler) kommt bei Zeile 15,16 und auch bei Zeile 30, also jeweils bei

    VB.NET-Quellcode

    1. (y, x)
    der Fehler: "Die Indexzahl ist größer als die Anzahl Dimensionen des indizierten Arrays".
    Hab mir zwar die Hilfe durchgelesen, werde aber daraus irgendwie nicht schlau.
    Ich hab den Fehler zwar wie folgt wegbekommen, nur gibt mir die Textbox nix aus, ist also wohl immernoch falsch, also ich hab es jetzt so:

    VB.NET-Quellcode

    1. Dim KartenArray() As Integer
    2. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles KartenLegen.Click
    3. Dim i As Integer, j As Integer
    4. Dim x As Integer, y As Integer
    5. Dim KartenArray(3, 3) As Integer
    6. ReDim KartenArray(3, 3)
    7. Randomize()
    8. For i = 1 To 8
    9. For j = 1 To 2
    10. Do
    11. x = CInt(Int(3 * Rnd()))
    12. y = CInt(Int(3 * Rnd()))
    13. Loop Until KartenArray(x, y) = 0
    14. KartenArray(x, y) = i
    15. Next j
    16. Next i
    17. End Sub
    18. Private Sub KartenZeichnen()
    19. Dim x As Integer, y As Integer
    20. Dim KartenArray(3, 3) As Integer
    21. ReDim KartenArray(3, 3)
    22. TextBox1.Text = ""
    23. For y = 0 To 3
    24. For x = 0 To 3
    25. TextBox1.Text = TextBox1.Text & KartenArray(x, y) & vbTab
    26. Next x
    27. TextBox1.Text = TextBox1.Text & vbCrLf
    28. Next y
    29. End Sub


    Hab also einfach bei Zeile 5 und bei Zeile 22 ein

    VB.NET-Quellcode

    1. Dim KartenArray(3, 3) As Integer
    eingefügt und bei Zeile 23 ein

    VB.NET-Quellcode

    1. ReDim KartenArray(3, 3)


    Aber wie gesagt, ich habe es falsch verändert. Es liegt warscheinlich daran (das bei mir der Fehler kommt), dass ich VB2003.net habe.

    Hoffe, ihr könnt mir nochmals helfen,

    Gruß Michi
    Hi!

    Der Fehler liegt daran, dass ich mit Arrays in VB.net einfach nich umgehen kann :D
    Nur in VB6 und C#... -.-

    Also ne schnelle Lösung ohne viel nachzudenken:
    Statt

    VB.NET-Quellcode

    1. Dim KartenArray() As Integer 'Leeres Kartengitter definieren
    machst du einfach

    VB.NET-Quellcode

    1. Dim KartenArray(3, 3) As Integer 'Leeres Kartengitter definieren

    Der Rest bleibt gleich.


    mfG Andy
    so, ich hab jetzt ne Weile keine Zeit gehabt weiter zu probieren und muss leider feststellen, dass das Beispiel bei mir immer noch nicht läuft. Das Programm hängt sich einfach auf...
    Ich hab den Quellcode jetzt so, vielleicht hab ich da einfach ein Fehler drin:

    VB.NET-Quellcode

    1. Option Explicit On
    2. Dim KartenArray(3, 3) As Integer
    3. Private Sub Kartenlegen()
    4. Dim i As Integer, j As Integer
    5. Dim x As Integer, y As Integer
    6. ReDim KartenArray(3, 3)
    7. Randomize()
    8. For i = 1 To 8
    9. For j = 1 To 2
    10. Do
    11. x = CInt(Int(3 * Rnd()))
    12. y = CInt(Int(3 * Rnd()))
    13. Loop Until KartenArray(x, y) = 0
    14. KartenArray(x, y) = i
    15. Next j
    16. Next i
    17. End Sub
    18. Private Sub KartenZeichnen()
    19. Dim x As Integer, y As Integer
    20. TextBox1.Text = ""
    21. For y = 0 To 3
    22. For x = 0 To 3
    23. TextBox1.Text = TextBox1.Text & KartenArray(x, y) & vbTab
    24. Next x
    25. TextBox1.Text = TextBox1.Text & vbCrLf
    26. Next y
    27. End Sub
    28. Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    29. Kartenlegen()
    30. KartenZeichnen()
    31. End Sub

    Wenn ich bei Zeile 16, dass

    VB.NET-Quellcode

    1. KartenArray(x, y) = i
    , was ja fürs Speichern zuständig ist, einfach mal wegmache, dann läuft das Beispiel. Die Textbox zeigt mir zwar ja nur nullen an, aber wenigstens läuft das Programm dann. Es wird vielleicht an Zeile 16 liegen.

    Gruß Michi
    Hi!

    Es war ein kleiner Fehler in der Zufallsfunktion.
    (ein 3er statt dem richtigen 4er)

    VB.NET-Quellcode

    1. Private Sub Kartenlegen()
    2. Dim i As Integer, j As Integer
    3. Dim x As Integer, y As Integer
    4. ReDim KartenArray(3, 3)
    5. Randomize()
    6. For i = 1 To 8
    7. For j = 1 To 2
    8. Do
    9. x = CInt(Int(4 * Rnd()))
    10. y = CInt(Int(4 * Rnd()))
    11. Loop Until KartenArray(x, y) = 0
    12. KartenArray(x, y) = i
    13. Next j
    14. Next i
    15. End Sub



    mfG Andy


    EDIT:
    Ich hab das Topic endlich mal verschoben und den Titel etwas eindeutiger gemacht.

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

    Hi

    Bin mittlerweile schon ganz gut vorangekommen, allerdings hab ich mit den vergleichen zweier Bilder Probleme. Wenn eben die 2 angeklickten Bilder nicht übereinstimmen, soll ja das Standardbild wieder angezeigt werden. Allerdings merkt sich das Programm nur das zuletzt angeklickte Bild.:

    VB.NET-Quellcode

    1. Private Sub Picture1_Click
    2. Dim Index As Short = Picture3.GetIndex(eventSender)
    3. Dim x As Short
    4. Dim i As Short
    5. Dim zwischen As Short
    6. zwischen = CShort(CObj(Picture1(Index).Image))
    7. If click < 2 Then Picture1(Index).Image = System.Drawing.Image.FromFile(VB6.GetPath & "\" & CStr(KartenArray(Index)) & ".jpg")
    8. If click = 0 Then Karte1 = KartenArray(Index)
    9. If click= 1 Then Karte2 = KartenArray(Index)
    10. MsgBox(CStr(KartenArray(Index)) & " " & CStr(Karte1) & " " & CStr(Karte2))
    11. End If
    12. click= click + 1
    13. If click = 2 Then
    14. If Karte1 <> Karte2 Then
    15. Picture1(Index).Image = System.Drawing.Image.FromFile(VB6.GetPath & "\A.jpg")
    16. End If
    17. End If
    18. If click = 2 Then click = 0


    Damit auch das erste angeklickte Bild im Picture1(index) gemerkt wird, möchte ich halt das Picture1(index) nach dem ersten durchlauf als "zwischen" speichern. Daher möchte ich das Picture1(index) als Short konvertieren. (siehe Zeile: 7) Allerdings kommt dabei die Meldung: "Zusätzliche Informationen: Ungültige Konvertierung von Typ 'Bitmap' in Typ 'Short'." Ich hoffe, jemand kann mir helfen.

    Gruß Michi
    Hi!

    Du kannst kein Objekt als Short zwischenspeichern, sondern nur eine Referenz darauf. Als zusätzliches "Gem" solltest du auch nur eine Click-Routine für alle PictureBoxen verwenden.

    VB.NET-Quellcode

    1. Private ClickStack(1) as Picturebox
    2. Private Sub Form_Load (...)
    3. ClickStack(0) = nothing
    4. ClickStack(1) = nothing
    5. AddHandler Picture1.Click, AddressOf Pictures_Click
    6. AddHandler Picture2.Click, AddressOf Pictures_Click
    7. AddHandler Picture3.Click, AddressOf Pictures_Click
    8. AddHandler Picture4.Click, AddressOf Pictures_Click
    9. AddHandler Picture5.Click, AddressOf Pictures_Click
    10. AddHandler Picture6.Click, AddressOf Pictures_Click
    11. AddHandler Picture7.Click, AddressOf Pictures_Click
    12. AddHandler Picture8.Click, AddressOf Pictures_Click
    13. AddHandler Picture9.Click, AddressOf Pictures_Click
    14. AddHandler Picture10.Click, AddressOf Pictures_Click
    15. AddHandler Picture11.Click, AddressOf Pictures_Click
    16. AddHandler Picture12.Click, AddressOf Pictures_Click
    17. AddHandler Picture13.Click, AddressOf Pictures_Click
    18. AddHandler Picture14.Click, AddressOf Pictures_Click
    19. AddHandler Picture15.Click, AddressOf Pictures_Click
    20. AddHandler Picture16.Click, AddressOf Pictures_Click
    21. 'bisheriger Form_Load-Code
    22. End Sub
    23. Private Sub Pictures_Click(Sender as Object, e as EventArgs)
    24. If (ClickStack(0) is nothing) or (ClickStack(1) is nothing) then
    25. if ClickStack(0) is nothing then
    26. ClickStack(0) = Sender
    27. else
    28. ClickStack(1) = Sender
    29. end if
    30. else
    31. 'prüfen, ob die Bilder ident sind
    32. 'u.U. Bilder per ClickStack(0).Image = ... und ClickStack(1).Image = ... zurück setzen
    33. 'Stack leeren
    34. ClickStack(0) = Nothing
    35. ClickStack(1) = Nothing
    36. End if
    37. End Sub



    mfG Andy

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