3-dimensionale Integer ansprechen bzw.ändern

  • VB.NET

Es gibt 18 Antworten in diesem Thema. Der letzte Beitrag () ist von Samus Aran.

    3-dimensionale Integer ansprechen bzw.ändern

    Hallo , bin gerade dabei ein kleines Tic Tac Toe Spiel zu machen , welches auf Rechtecken , Bitmaps und einem X-Y-Koordinatensystem basiert.

    Bis jetzt lief alles wie ich es wollte:
    >Rechtecke werden gezeichnet
    > X und O werden abwechselnd ins jeweilig angeklickte Kästchen gezeichnet.

    Mein Problem ist jetzt die Umsetzung das man nicht mehr in ein bereits gefülltes Kästchen klicken kann.

    Also ich stelle mir das so vor

    VB.NET-Quellcode

    1. 'Koordinaten der Rechtecke und ihr Zustand
    2. 'Erste Zahl = X-Wert , Zweite Zahl = Y-Wert , Dritte Zustand des Rechtecks
    3. 'Die Dim's müssen eventuell umbenannt werden um mit Arrays zu arbeiten der das Problem vielleicht löst?
    4. Dim OLiCo(1, 1, 0) As Integer
    5. Dim OMitCo(2, 1, 0) As Integer
    6. Dim OReCo(3, 1, 0) As Integer
    7. Dim MLiCo(1, 2, 0) As Integer
    8. Dim MMitCo(2, 2, 0) As Integer
    9. Dim MReCo(3, 2, 0) As Integer
    10. Dim ULiCo(1, 3, 0) As Integer
    11. Dim UMitCo(2, 3, 0) As Integer
    12. Dim UReCo(3, 3, 0) As Integer


    das sind die 9 rechtecke samt Koordinaten , die 0 representiert den Wert der eingetragen ist , also gar nichts , zumindest am Anfang später soll für X 1 , und für O 2 eingetragen werden.

    Das zeichnen erfolgt durch ein Mausklick Event:

    VB.NET-Quellcode

    1. Private Sub Main_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseClick
    2. SpielerNOW = SpielerNOW + 1
    3. ' Von dem hängt die Farbe ab. bzw in dem Fall obs X oder O ist
    4. If SpielerCurrent = 1 Then
    5. PaintBrush = 1
    6. End If
    7. If SpielerCurrent = 2 Then
    8. PaintBrush = 2
    9. End If
    10. Select Case PaintBrush
    11. Case 0 'Leer
    12. Überprüfe ob Rechteck schon X oder O enthält 'in dem Fall bricht es ab. Wie ich das mache weiß ich , aber ich muss zuerst so ne Art Speicher die deren 'Zustände speichert machen
    13. Map(mMapX, mMapY, 0) = 0
    14. WriteStatusofRectangle()
    15. Case 1 'X
    16. Map(mMapX, mMapY, 0) = 1 '<-- malt in das Rechteck ein X
    17. WriteStatusofRectangle()
    18. Case 2 'O
    19. Map(mMapX, mMapY, 0) = 2
    20. WriteStatusofRectangle()
    21. End Select
    22. End Sub


    WriteStatusofRectangle ist eine Funktion die aus "Dim OLiCo(1, 1, 0) As Integer" , Dim OLiCo(1, 1, 1) As Integer machen soll.

    Was ich noch machen muss ist das wenn dieser Wert nicht 0 entspricht , der Sub beendet wird , also nichts reingezeichnet wird.

    Mein Problem ist jetzt den Status in den 3-dimensionalen Integer (ist doch einer?) zu schreiben , also an die letzte Stelle.
    Und der muss später auch ausgelesen zu werden , um den Sub zu beenden wenn das Rechteck schon X oder O hat.

    Also nochmal so wie ich mir den Code vorstelle , an dem ich nach mehreren Array Tuts von Youtube scheitere:

    VB.NET-Quellcode

    1. Private Function WriteStatusofRectangle() As Integer
    2. Lies X,Y Wert von dem angeklickten Rechteck
    3. Gehe zu der Variable dessen Wert geändert werden muss
    4. Ändere 3 Stelle die Zustand des Rechtecks angibt
    5. End Function


    Ja ich weiß ne Funktion muss mit Return gemacht werden ^^

    Also nochmal kurz: So ne Art Speicher der die Zustände der Rechtecke speichert.

    THX im Voraus :D

    VB.NET-Quellcode

    1. Dim dict As Dictionary(Of Typ(), Nullable(Of Boolean))

    So..du kannst nun nach True, False, Nothing überprüfen.

    VB.NET-Quellcode

    1. If dict(Typ(1, 1).Value = True Then
    2. ElseIf dict(Typ(1, 1).Value = False Then
    3. ElseIf dict(Typ(1, 1).Value = Nothing Then
    4. End If

    Du wolltest doch: True, False, Nix.
    Nix is in dem Fall Nothing.

    AliveDevil schrieb:

    If dict(Typ(1, 1).Value = True Then
    ElseIf dict(Typ(1, 1).Value = False Then
    ElseIf dict(Typ(1, 1).Value = Nothing Then
    End If

    AliveDevil schrieb:

    Du wolltest doch: True, False, Nix.
    Nix is in dem Fall Nothing.

    AliveDevil schrieb:

    VB.NET-Quellcode

    1. Dim dict As Dictionary(Of Typ(), Nullable(Of Boolean))

    So..du kannst nun nach True, False, Nothing überprüfen.

    VB.NET-Quellcode

    1. If dict(Typ(1, 1).Value = True Then
    2. ElseIf dict(Typ(1, 1).Value = False Then
    3. ElseIf dict(Typ(1, 1).Value = Nothing Then
    4. End If

    Du wolltest doch: True, False, Nix.
    Nix is in dem Fall Nothing.


    Also dort wo das 1,1 ist könnte ich meine X-Y-Koordinaten speichern?
    Für jedes der anderen Kästchen muss ich auch sowas erstellen? (also 9 mal?)
    Kleiner Ansporn: Zum Speichern von 3x3 Feldern reicht ein Array mit 9 Plätzen.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Enum enFeld
    2. unbelegt
    3. X
    4. O
    5. End Enum

    VB.NET-Quellcode

    1. Dim feld(8) As enFeld
    2. Function getFieldValue(Reihe As Integer, Spalte As Integer) As enFeld
    3. Dim feldnummer As Integer
    4. feldnummer = ((Reihe - 1) * 3) + Spalte
    5. Return feld(feldnummer)
    6. End Function

    VB.NET-Quellcode

    1. Sub setFieldValue(reihe As Integer, spalte As Integer, wert As enFeld)
    2. Dim feldnummer As Integer
    3. feldnummer = ((reihe - 1) * 3) + spalte
    4. feld(feldnummer) = wert
    5. End Sub


    Bitte keine Vollzitate. Zitiere höchstens den Teil, auf den du eine Antwort gibst.
    Eleganz ist relativ :D

    Für ein TripleState-Feld nehme ich immer Enums. Irgendwie bin ich der Meinung, dass bei einem TicTacToe-Spiel der Optimierungsbedarf nicht so hoch sein wird.
    Da frage ich lieber ab, ob X oder O, anstatt Ja oder Nein.
    Meine Variante ist lesbarer.

    Spieler X klickt auf Feld:

    VB.NET-Quellcode

    1. feld = enFeld.X
    2. 'vs. :
    3. feld = TRUE

    Bei deiner Variante kann man wiederum mit dem Speicherverbrauch argumentieren. Dies dürfte hier jedoch zu vernachlässigen sein.
    @der_Kurt

    Ok habe das an meinen Source Code angepasst , aber ich hab zu deinem noch Fragen:

    Spoiler anzeigen
    Was macht das hier? die 8 ist nicht nachvollziehbar....

    VB.NET-Quellcode

    1. Dim feld(8) As enFeld


    Warum ist das ein Sub und keine Funktion?

    VB.NET-Quellcode

    1. Sub setFieldValue(reihe As Integer, spalte As Integer, wert As enFeld)
    2. Dim feldnummer As Integer
    3. feldnummer = ((reihe - 1) * 3) + spalte
    4. feld(feldnummer) = wert
    5. End Sub


    Und setzt

    VB.NET-Quellcode

    1. feld(feldnummer) = wert
    den Wert bzw. wie bestimme ich den?
    Hier wird ein Array mit 9 Feldern angelegt, beginnend bei 0. (0 bis 8 sind 9 Felder).

    Thema Sub/Function:
    SetFieldValue setzt einen Wert, die übergebenen Parameter sind die Reihe, die Spalte, und der Wert. Hier habe ich keinen Rückgabewert. Deshalb reicht eine Sub.
    Bei GetFieldValue frage ich einen Wert ab (Parameter Reihe und Spalte). Dieser Wert muss übergeben werden, deshalb eine Function.

    Das Beispiel von mir war ein spielerischer Ansatz. Du darfst ruhig etwas weiter experimentieren.
    Ok hab jetzt endlich herausgefunden wie das geht :D

    Ich habs jetzt so das beim Form_Load Event nach dem Zeichnen alle Felder

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Call setFieldValue(1, 1, enFeld.unbelegt)
    2. Call setFieldValue(2, 1, enFeld.unbelegt)
    3. Call setFieldValue(3, 1, enFeld.unbelegt)
    4. usw....


    den Zustand unbelegt erhalten.
    Beim MausClick Event hab ich jetzt auch neben dem Zeichnen der X und O eine MsgBox welche mir den Wert der gerade gezeichneten anzeigt.

    So schön so gut , dafür hatte ich den Fehler: Array IndexOutofRangeException , bei der alles einfrierte

    Aber nach der Änderung von Dim feld(8) As enFeld auf Dim feld(9) As enFeld ging es ?( reibungslos....

    Aufjedenfall THX euch allen!! :love:

    IDarkThunderI schrieb:

    Aber nach der Änderung von Dim feld(8) As enFeld auf Dim feld(9) As enFeld ging es ?( reibungslos....

    aber besser wärs aber, du verstündest, dass Arrays nullbasiert sind.

    vmtl. hast du iwo eine falsch ausgelegte Zählschleife, aber um das zu untersuchen müssteste den Code zeigen

    FreakJNS schrieb:

    Ich glaube er weiß garnicht was schleifen sind, sonst wurde er die Zuweisung der feldzustände damit realisieren... Das "Fall" ist übrigens auch veralteter Unfug => weglassen!

    Schleifen angucken! ;)


    Ich weiß dass dies schlecht ist , nehmen wir an ich hab ein 1000*1000 Feld , da müsste ich ja eine Million mal alles reinhauen :P

    Jetzt habe ich es eh so gemacht

    Spoiler anzeigen

    VB.NET-Quellcode

    1. For iX = 0 To 2 'dreimal , da 3*3 Feld
    2. For iY = 0 To 2 'dreimal , da 3*3 Feld
    3. Call setFieldValue(iX, iY, enFeld.unbelegt)
    4. Next
    5. Next
    Mach das Call da mal weg. Wir schreiben das Jahr 2012.
    Edit: Kleines Update bzgl. Nullable:

    VB.NET-Quellcode

    1. Dim bool? As Boolean = Nothing
    scheint auch zu funktionieren. In dem Fall steht das ? für Nullable.

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