VBAnfänger TicTacToe Spiel Programm ist fertig und läuft ABER wie "schlimm" ist der Code ?

    • Beta
    • Open Source

    Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von SpaceyX.

      VBAnfänger TicTacToe Spiel Programm ist fertig und läuft ABER wie "schlimm" ist der Code ?

      Moin Leute,

      auf Anregung aus einem anderen Thread hier meine Umsetzung eines TicTacToe Spiels. Der Code ist lauffähig (mit Option Strict on). Im Anhang noch eine Compilierte .exe, um besser zu sehen was passiert.

      Habe ich grobe Design Fehler im Aufbau des Codes gemacht oder sonstige Entscheidungen getroffen die ich mir nicht aneignen sollte für spätere Projekte. Geht es anders viel besser.

      Ganz klar wird das mit JA zu beantworten sein. Falls möglich dann noch kurz sagen, wie wichtig es wäre das zu ändern (Einschätzung der Dringlichkeit/Wichtigkeit) oder ist es eher eine Geschmackssache.
      (den Thread [Sammelthread] Code-Korrektur hab ich wahrgenommen. Denke mein Bsp. ist zu groß dafür. Falls nicht gerne dorthin verschieben).

      Erklärung was das Programm macht:




      Es soll ein TicTacToe Clone sein 3 gleiche Symbole in Reihe, Spalte oder Diagonale gewinnt. Es wird abwechselt gezogen. Feld ist 3x3 groß.

      Struktur:
      Form1 -> im Grunde keine Logik Entscheidungen oder Variablen, es werden nur die nötigen Subs und Funktionen in Modul2 in der richtigen Reihenfolge aufgerufen sobald der User ein Feld angeklickt hat.

      wichtige Methoden des Moduls

      ResetGame ()-> setzt alle Felder und Checkboxen etc. wieder auf Anfang. Belegt das Spielfeld mit String " " das symbolisiert, dass das Feld frei ist und noch nicht gespielt wurde

      UserMove () -> Speichert ins SpielstandArray "0" (Spielstein des Users) beim Index der der Nummer der angeklickten Box entspricht.

      Spielfeld ist so im Array angelegt
      0 1 2
      3 4 5
      6 7 8
      Falls der User Textbox 1 anklickt wird an Arraystelle 1 eine "0" gespeichert und im Feld angezeigt

      DidIWin ()-> schaut nach ob im SpielstandArray drei gleiche Symbole vorliegen.

      4 mal 2 For next Schleifen

      Alle Zeilen werden durchgesehen
      (0 1 2) (3 4 5 ) (6 7 8)
      Alle Spalten
      (0 3 6) (1 4 7) (2 5 8)
      & beide Diagonalen
      (0 4 8) und (2 4 6)

      BotLvl0 () -> bei Level 0 wählt die CPU einfach ein Zufälliges freies Feld aus
      Erst wird geschaut wie viele Freiespielfelder noch existieren (ist abhängig wie viele Züge schon gespielt wurden). Dann wird eine Zufallszahl generiert aus der Menge 1 bis Anzahl freie Felder.
      Bsp:
      0 X 0
      0 - X
      - - -
      Anzahl freie Felder 4 -> Zufallszahl von 1-4 = 2 -> das zweite Freifeld wird als gewählt angezeigt
      0 X 0
      0 - X
      X - -


      BotLvl1()-> ruft Bestmove() ->
      Es wird wie bei 3 Gleiche in Reihe gesucht nach 2 in "Reihe/Spalte/Diag." und falls es dazu noch ein freies Feld in dieser "Reihe/Spalte/Diag." gibt ist das beste Feld.
      Falls da nichts gefunden wird wird Level0 aufgerufen und ein Zufallsfeld genommen.

      BotLvl2() -> hab ich nicht fertig und daher auf nicht sichtbar gestellt

      Spoiler anzeigen
      FORM1

      VB.NET-Quellcode

      1. Option Strict On
      2. Public Class Form1
      3. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
      4. Randomize()
      5. ResetGame()
      6. End Sub
      7. Private Sub CheckBoxBot_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBoxBot.CheckedChanged
      8. If CheckBoxBot.Checked = True Then
      9. CheckBoxBot.Enabled = False
      10. LblTop.Focus()
      11. BotMove()
      12. End If
      13. End Sub
      14. Private Sub Txboxes_clicked(sender As Object, e As EventArgs) Handles Txb0.Click, Txb1.Click, Txb2.Click, Txb3.Click,
      15. Txb4.Click, Txb5.Click, Txb6.Click, Txb7.Click, Txb8.Click
      16. 'Late Binding ist nicht erlaubt daher mit direct cast
      17. Dim ClickedBox As String
      18. ClickedBox = DirectCast(sender, TextBox).Name
      19. UserMove(ClickedBox) 'Starte Sub mit "Welche Textbox hat der User angeclicked"
      20. DidIWin()
      21. If Ende = False Then
      22. BotMove()
      23. DidIWin()
      24. End If
      25. If Ende Then
      26. Ergebnise()
      27. Exit Sub
      28. End If
      29. End Sub
      30. Private Sub BtnReset_Click(sender As Object, e As EventArgs) Handles BtnReset.Click
      31. ResetGame()
      32. End Sub
      33. End Class



      Modul

      VB.NET-Quellcode

      1. Option Strict On
      2. Module Module2
      3. Dim FreiesFeldZeichen As String = " "
      4. Dim HumanPlays0 As String = "0"
      5. Dim BotplaysX As String = "X"
      6. Dim SpielStandArray(8) As String
      7. Dim WinFieldHuman As Integer = -1
      8. Dim WinfieldBot As Integer = -1
      9. Dim HWins As Integer = 0
      10. Dim BWins As Integer = 0
      11. Dim Draw As Integer = 0
      12. Dim SpielfeldBoxen As TextBox() = {Form1.Txb0, Form1.Txb1, Form1.Txb2, Form1.Txb3, Form1.Txb4, Form1.Txb5, Form1.Txb6, Form1.Txb7, Form1.Txb8}
      13. Dim UserMoveArray(5) As Integer 'Array index des User Moves für Botlevl 2
      14. Dim UsermoveCounter As Integer = 0
      15. Dim BotMoveArray(5) As Integer 'Array index des Bots Moves für Botlevl 2
      16. Dim BotMoveCounter As Integer = 0
      17. Dim Count0 As Integer 'Human
      18. Dim CountX As Integer 'CPU
      19. Dim FreiesFeldIn3erReihe As Integer = -1 'falls es so was wie X -- X gibt wird der Index des FreienFeldes hier gespeichert
      20. Public SpielTiefe As Integer = 1
      21. Public Ende As Boolean = False
      22. Sub ResetGame()
      23. For i = 0 To 8
      24. SpielfeldBoxen(i).Text = FreiesFeldZeichen 'wird mit z.B. String " " vorbelegt
      25. SpielfeldBoxen(i).Enabled = True
      26. SpielStandArray(i) = FreiesFeldZeichen
      27. Next
      28. SpielTiefe = 1
      29. WinFieldHuman = -1
      30. WinfieldBot = -1
      31. Form1.CheckBoxBot.Enabled = True
      32. Form1.CheckBoxBot.Checked = False
      33. Ende = False
      34. For i = 0 To 4
      35. BotMoveArray(i) = -1
      36. UserMoveArray(i) = -1
      37. Next
      38. BotMoveCounter = 0
      39. UsermoveCounter = 0
      40. End Sub
      41. Sub UserMove(ByVal ClickedBoxName As String)
      42. For i = 0 To 8
      43. If SpielfeldBoxen(i).name = ClickedBoxName Then
      44. SpielStandArray(i) = HumanPlays0
      45. SpielfeldBoxen(i).Text = HumanPlays0
      46. SpielfeldBoxen(i).Enabled = False
      47. UserMoveArray(UsermoveCounter) = i
      48. Form1.LblTop.Focus()
      49. Exit For
      50. End If
      51. Next
      52. Form1.CheckBoxBot.Enabled = False 'User hat angefangen also kann Bot nicht mehr anfangen
      53. UsermoveCounter += 1
      54. SpielTiefe += 1
      55. End Sub
      56. Sub Count3Win()
      57. If Count0 = 3 Or CountX = 3 Then
      58. If Count0 = 3 Then
      59. MsgBox("Humans win!")
      60. Ende = True
      61. HWins += 1
      62. Exit Sub
      63. End If
      64. If CountX = 3 Then
      65. MsgBox("Oh my God Bot wins!")
      66. Ende = True
      67. BWins += 1
      68. Exit Sub
      69. End If
      70. End If
      71. End Sub
      72. Sub DidIWin()
      73. 'Zeilen nach 3 Gleichen in Reihe duchsuchen
      74. '0 1 2
      75. '3 4 5 wird zu (0 1 2) (3 4 5) (6 7 8)
      76. '6 7 8
      77. For i = 0 To 2
      78. Count0 = 0
      79. CountX = 0
      80. For j = 0 To 2
      81. If SpielStandArray(i * 3 + j) = HumanPlays0 Then Count0 += 1
      82. If SpielStandArray(i * 3 + j) = BotplaysX Then CountX += 1
      83. Next
      84. Count3Win()
      85. If Ende = True Then Exit Sub
      86. Next
      87. 'Spalten nach 3 Gleichen durchsuchen
      88. '0 1 2
      89. '3 4 5 wird zu (0 3 6) (1 4 7) (2 5 8)
      90. '6 7 8
      91. For k = 0 To 2
      92. Count0 = 0
      93. CountX = 0
      94. For l = 0 To 6 Step 3
      95. If SpielStandArray(k + l) = HumanPlays0 Then Count0 += 1
      96. If SpielStandArray(k + l) = BotplaysX Then CountX += 1
      97. Next
      98. Count3Win()
      99. If Ende = True Then Exit Sub
      100. Next
      101. 'Diagonalen nach 3 Gleichen durchsuchen
      102. '0 1 2
      103. '3 4 5 wird zu (0 4 8) (2 4 6)
      104. '6 7 8
      105. '
      106. 'Erste Diagonale (0 4 8)
      107. Count0 = 0
      108. CountX = 0
      109. For m = 0 To 8 Step 4
      110. If SpielStandArray(m) = HumanPlays0 Then Count0 += 1
      111. If SpielStandArray(m) = BotplaysX Then CountX += 1
      112. Next
      113. Count3Win()
      114. If Ende = True Then Exit Sub
      115. 'Zweiter Diagonale (2 4 6)
      116. Count0 = 0
      117. CountX = 0
      118. For n = 2 To 6 Step 2
      119. If SpielStandArray(n) = HumanPlays0 Then Count0 += 1
      120. If SpielStandArray(n) = BotplaysX Then CountX += 1
      121. Next
      122. Count3Win()
      123. If Ende = True Then Exit Sub
      124. 'Falls keine 3 in Reihe gefunden wurden und der letzte Zug 10 war ist es ein Draw
      125. If SpielTiefe = 10 Then
      126. MsgBox("We will see us again Human!")
      127. Ende = True
      128. Draw += 1
      129. End If
      130. End Sub
      131. Sub BotMove()
      132. If Form1.OptLvl0.Checked Then BotMoveLvl0()
      133. If Form1.OptLvl1.Checked Then BotMoveLvl1()
      134. If Form1.OptLvl2.Checked Then BotMoveLvl2()
      135. End Sub
      136. Sub BotMoveLvl0() 'Bot selects random FreeField
      137. Dim AnzahlFreierFelder As Integer = 10
      138. Dim ZufallsFeldZahl As Integer
      139. Dim count As Integer = 0
      140. AnzahlFreierFelder -= SpielTiefe
      141. ZufallsFeldZahl = Convert.ToInt32(Math.Floor(Rnd() * AnzahlFreierFelder)) + 1
      142. For i = 0 To 8
      143. If SpielStandArray(i) = FreiesFeldZeichen Then count += 1
      144. If count = ZufallsFeldZahl Then
      145. SpielStandArray(i) = BotplaysX
      146. SpielfeldBoxen(i).text = BotplaysX
      147. SpielfeldBoxen(i).Enabled = False
      148. Form1.LblTop.Focus()
      149. Exit For
      150. End If
      151. Next
      152. SpielTiefe += 1
      153. End Sub
      154. Sub BotMoveLvl1()
      155. BestMoves() 'looks for 2 in a Row for Human0 and for BotX
      156. 'and stores a possible freefield index Array Nr. in WinfieldHuamn and WinfieldBot
      157. If WinfieldBot <> -1 Then
      158. SpielStandArray(WinfieldBot) = BotplaysX
      159. SpielfeldBoxen(WinfieldBot).text = BotplaysX
      160. SpielfeldBoxen(WinfieldBot).Enabled = False
      161. Form1.LblTop.Focus()
      162. SpielTiefe += 1
      163. ElseIf WinFieldHuman <> -1 Then
      164. SpielStandArray(WinFieldHuman) = BotplaysX
      165. SpielfeldBoxen(WinFieldHuman).text = BotplaysX
      166. SpielfeldBoxen(WinFieldHuman).Enabled = False
      167. Form1.LblTop.Focus()
      168. SpielTiefe += 1
      169. Else
      170. BotMoveLvl0()
      171. End If
      172. End Sub
      173. Sub BotMoveLvl2()
      174. 'kommt noch
      175. End Sub
      176. Sub BestMoves() 'looks for 2 in a Row 0 or X and saves the index of a possible freefield
      177. FreiesFeldIn3erReihe = -1 'equals kein freies Feld
      178. WinfieldBot = -1
      179. WinFieldHuman = -1
      180. 'Zeilen nach 2 Gleichen in Reihe duchsuchen
      181. '0 1 2
      182. '3 4 5 wird zu (0 1 2) (3 4 5) (6 7 8)
      183. '6 7 8
      184. For i = 0 To 2
      185. Count0 = 0
      186. CountX = 0
      187. FreiesFeldIn3erReihe = -1
      188. For j = 0 To 2
      189. If SpielStandArray(i * 3 + j) = FreiesFeldZeichen Then FreiesFeldIn3erReihe = (i * 3 + j)
      190. If SpielStandArray(i * 3 + j) = HumanPlays0 Then Count0 += 1
      191. If SpielStandArray(i * 3 + j) = BotplaysX Then CountX += 1
      192. Next
      193. If Count0 = 2 And FreiesFeldIn3erReihe <> -1 Then WinFieldHuman = FreiesFeldIn3erReihe
      194. If CountX = 2 And FreiesFeldIn3erReihe <> -1 Then WinfieldBot = FreiesFeldIn3erReihe
      195. Next
      196. 'Spalten nach 2 Gleichen durchsuchen
      197. '0 1 2
      198. '3 4 5 wird zu (0 3 6) (1 4 7) (2 5 8)
      199. '6 7 8
      200. For k = 0 To 2
      201. Count0 = 0
      202. CountX = 0
      203. FreiesFeldIn3erReihe = -1
      204. For l = 0 To 6 Step 3
      205. If SpielStandArray(k + l) = FreiesFeldZeichen Then FreiesFeldIn3erReihe = (k + l)
      206. If SpielStandArray(k + l) = HumanPlays0 Then Count0 += 1
      207. If SpielStandArray(k + l) = BotplaysX Then CountX += 1
      208. Next
      209. If Count0 = 2 And FreiesFeldIn3erReihe <> -1 Then WinFieldHuman = FreiesFeldIn3erReihe
      210. If CountX = 2 And FreiesFeldIn3erReihe <> -1 Then WinfieldBot = FreiesFeldIn3erReihe
      211. Next
      212. 'Diagonalen nach 2 Gleichen durchsuchen
      213. '0 1 2
      214. '3 4 5 wird zu (0 4 8) (2 4 6)
      215. '6 7 8
      216. '
      217. 'Erste Diagonale (0 4 8)
      218. Count0 = 0
      219. CountX = 0
      220. FreiesFeldIn3erReihe = -1
      221. For m = 0 To 8 Step 4
      222. If SpielStandArray(m) = FreiesFeldZeichen Then FreiesFeldIn3erReihe = (m)
      223. If SpielStandArray(m) = HumanPlays0 Then Count0 += 1
      224. If SpielStandArray(m) = BotplaysX Then CountX += 1
      225. Next
      226. If Count0 = 2 And FreiesFeldIn3erReihe <> -1 Then WinFieldHuman = FreiesFeldIn3erReihe
      227. If CountX = 2 And FreiesFeldIn3erReihe <> -1 Then WinfieldBot = FreiesFeldIn3erReihe
      228. 'Zweiter Diagonale (2 4 6)
      229. Count0 = 0
      230. CountX = 0
      231. FreiesFeldIn3erReihe = -1
      232. For n = 2 To 6 Step 2
      233. If SpielStandArray(n) = FreiesFeldZeichen Then FreiesFeldIn3erReihe = (n)
      234. If SpielStandArray(n) = HumanPlays0 Then Count0 += 1
      235. If SpielStandArray(n) = BotplaysX Then CountX += 1
      236. Next
      237. If Count0 = 2 And FreiesFeldIn3erReihe <> -1 Then WinFieldHuman = FreiesFeldIn3erReihe
      238. If CountX = 2 And FreiesFeldIn3erReihe <> -1 Then WinfieldBot = FreiesFeldIn3erReihe
      239. End Sub
      240. Sub Ergebnise()
      241. Form1.LblScore.Text = "H:" & HWins & " D:" & Draw & " Bot:" & BWins
      242. For i = 0 To 8
      243. SpielfeldBoxen(i).Enabled = False
      244. Next
      245. Form1.BtnReset.Focus()
      246. End Sub
      247. End Module


      Ich freue mich auf Anregungen und bitte daran zu denken das ich noch ziemlich am Anfang stehe. Es sollte möglichst nicht zu abstrakt werden damit ich es noch verstehe. Am besten konkret mit Code. Danke und viel Spass...

      *Beitrag verschoben, langen Codeteil gespoilert und EXE aus Sicherheitsgründen entfernt (bitte Projektdateien hochladen)* ~NoFear23m
      Bilder
      • TicTacToeScreenshot.jpg

        14,79 kB, 169×284, 25 mal angesehen

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

      Wäre besser, Du lädst das Projekt anstatt der .exe Datei hoch. So kann man den Code gleich editieren. Die .exe wird niemand ausführen...
      Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
      Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o

      How to turn OPTION STRICT ON
      Why OPTION STRICT ON
      Welche Datein muß ich zippen damit ich alles vom Projekt drin habe, aber keine Persönliche Infos (git login, Name, etc) rausgebe?

      Alle rot eingekreisten Dateien und Ordner, wäre das richtig?
      Bilder
      • welche Datein.jpg

        38,1 kB, 329×446, 25 mal angesehen
      Du kannst bin,obj und alle versteckten Ordner , komplett löschen.
      den anderen git Kram eben auch noch und den Rest zippen.

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

      Hab mir mal die Zeit genommen und über den Code drübergeschaut. Auffällig ist, dass manche Kommentare auf englisch sind. Somit nehme ich an, dass nicht der komplette Code von Dir stammt? Ich lade Dir die "korrigierte" Version hier hoch. Die Verbesserungen sind absolut nicht optimal. Ich habe versucht, die Struktur wo möglich zu erhalten. Im Grunde kann man das nicht so programmieren. Alle Kommentare, die mit -> beginnen, stammen von mir. Was sich durch den kompletten Code gezogen hat, sind die Aufrufe von Controls aus dem Modul Form1.xxxx.xxxx. Diese sind ein absolutes NoGo! Wie in Deinem anderen Thread erwähnt, lies dringend das Tutorial von @RodFromGermany.

      Den kompletten Code aus Deinem Modul habe ich in eine Klasse ausgelagert und die unsäglichen Zugriffe auf die Controls hab ich korrigiert. Aber das ist auch weit fern von optimal. Module solltest Du generell sein lassen. Beschäftige Dich mit OOP (Object Oriented Programming). Bei Fragen immer gerne.
      Dateien
      Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
      Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o

      How to turn OPTION STRICT ON
      Why OPTION STRICT ON
      Option Strict On am besten projektweit einstellen
      VB6-Namespace entfernen -> Randomize fällt weg. Stattdessen einen .Net-Zufallsgenerator hernehmen:

      VB.NET-Quellcode

      1. Dim Random As New Random
      2. '...
      3. Random.Next(untereGrenze_Inklusive, obereGrenze_Exklusive)
      4. 'oder
      5. Random.Next(obereGrenze_Exklusive)

      dann kommt auch ne Ganzzahl raus und man kann sich Math.Floor und den Convert sparen.

      In Count3Win ist noch ne MsgBox drin.
      Beim schnellen Drüberschauen fiel auf: sehr/zu viele Game-Klassenvariablen. Das kann man durch richtigen Einsatz von Functions sicherlich stark minimieren - habe aber aufgrund von Zeitdruck keine Belege dafür.

      DidIWin? Prozedurnamen sollten keine Fragen sein, sondern Aufgabenbeschreibungen. Fragen könnte man notfalls bei Functions verwenden - denn diese können einen Wert, also quasi eine Antwort zurückgeben.

      Die Verwendung von TextBoxen in der Game-Klasse ist eine Festlegung, die sich später als schwerfälliger Anker erweisen dürfte. Wenn Du nämlich Deine GUI auf z.B. anklickbare PicBoxen umstellen willst, musst Du die Game-Klasse nachbearbeiten. Aber dieser Unabhängigkeitsschritt ist schon ne Stufe weiter, Du hast erstmal andere Probleme zu lösen, @nogood.
      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.
      Leute Danke
      bin erst mal baff, dass Ihr Euch dafür Zeit genommen habt. Danke.Danke
      Ich melde hier kurz zurück, dass ich die Posts gelesen habe. Ich muss die Vorschläge mit mehr Ruhe heute Abend durch-sehen // denken.


      @SpaceyX English und Deutsch-Mix ich konnte mich wohl nicht so ganz entscheiden und hab alle Variablen so benannt wie es für mich persönlich am meisten Sinn ergeben hat.
      Ich bin stolz (egal ob der Code gut oder schlecht ist) und kann sagen, der Code kommt 100% von mir (0% Copy-Paste). Ich kann ganz gut/okay Englisch verstehen; daher wohl der Mix. Man muss sagen auch keine so glückliche Entscheidung, wenn man an den Fall denkt, dass da auch mal wer anders drauf schaut.

      @ VaporiZed
      1 ) "Option Strict on" ist per Einstellungen in Visual Sudio default auf on gestellt (hab das Video von SpaceyX umgesetzt).
      2 ) VB6-NameSpace entfernen wie geht das ???
      3) .Net Zufallsgenerator Danke für den Code werde ich mir merken. Im letzten Buch (das ich dazu gelesen habe) VB 2017 steht das noch mit Randomize() drin
      3 ) "In Count3Win ist noch ne MsgBox drin." Ups da ist wohl noch was vom Debugen drin...
      4) Prozedurnamen nicht als Frage benennen auch zur Kenntnis genommen ().

      Du hast mir ja schon bei mehreren Fragen sehr geholfen und weißt das da noch so einiges im Argen liegt bei mir (Ich will mich auch unbedingt noch um das DataSet Thema kümmern).

      ----
      Als nächstes Projekt hab ich mir ein Programm zur Kundenzufriedenheit vorgenommen. Da wollte ich DataSet und auch das erste mal Klassen Objecte benutzen.

      Ich hab schon mal gelesen, dass die Benutzung von Modul nicht mehr zeitgemäß ist/sein soll. Wo soll der ganze Code den hin mein Bauchgefühl sagt mir das mehr als 500 Zeilen Code in einer Datei schon zu viel / zu unübersichtlich werden. Wie geht Ihr da vor? Mit #Region oder wird man so gut, dass man alles in Klassen/Objekten verpackt.

      Also bis später ...

      nogood schrieb:

      Mit #Region oder wird man so gut, dass man alles in Klassen/Objekten verpackt.
      Regions sind Ausblenderei. Es geht um vernünftige Codeerstellung. Und da VB.Net ne OOP-Sprache ist, wäre es sinnvoll, diese entsprechend auch zu verwenden. Stell Dir z.B. die Frage: Was wäre bei einem echten Spiel ein Objekt, was mit anderen interagiert? Du hättest das Spielfeld, den Spieler, den Gegenspieler. 3 Objekte, die an sich unabhängig voneinander mit anderen Objekten kommunizieren. Das ist eine Möglchkeit für einen OOP-Ansatz.
      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.
      @ SpaceyX

      1 ) "Im Grunde kann man das nicht so programmieren." Wie meinst Du das? Der ganze Code ist "eher Mist" oder meinst Du bei der Menge Code kann man nicht mal eben ein paar kleinere Änderungen rein werfen und dann wird alles Gold. Wenn man mehr Ahnung hat würde man sowie so ganz anders anfangen.

      2 ) "Form1.xxxx.xxxx. Diese sind ein absolutes NoGo!" Ich hab mir den verlinkten Thread von RodfromGermany und die folgenden Posts die letzte Stunde durchgelesen. Leider scheint mein Wissen von Klassen/Objecten und die entsprechenden Konsequenzen noch zu gering zu sein. Ich versteh die ganze Dringlichkeit nicht. Fällt Dir eventuell noch ein Link ein, wo so etwas auf einer noch simpleren Stufe erklärt wird. Me. // Sender as Object // Event Args usw. sind für mich noch Begriffe die ich zwar sehe und schon benutze ich aber nicht wirklich weiß was dahinter steht. Hoffe das das mit der Zeit besser wird.

      Z.B bei :
      Sub ClickBt1 (sender as Object, e as EventArgs) Handels button1.click (denke ich)->

      Sub = Methode(Funktion ohne Rüchgabewert; oder wie auch immer man das nennt)
      ClickBt1 = Name der Methode kann ich frei wählen
      (sender as Object, e as EventArgs) = die Methode bekommt 2 Werte beim Aufruf mit 1x sender as Object (wobei Sender für ein Control-Object steht z.B. TxtBox) und 1 x e als Auftretendes Event Argument so etwas wie clicked
      Handels button1.click = ??? also ist klar das es das Event ist button1.click aber so richtig hab ich da kein Gespür für

      3 )Deine Code Änderungen (ich versuch das mal in meinen Worten nachzuschreiben was Du geändert hast)
      "Private _game As TicTacToeGame '-> Anlegen der Game-Variablen" -> es wird eine Variabel der Klasse TicTacToeGame Angelegt
      in Sub Form1_Load (...)
      "_game = New TicTacToeGame({Me.Txb0, ...})" -> Instanzierung eines Objectes der Klasse TicTacToeGame mit Array von Objecten Txtboxen ; gespeichert in der Variable _game
      Hoffe ich verwende ansatzweise die richtigen Worte -> Überladung bei Aufruf der Sub New der Klasse TicTacToeGame und dort werden die TxtBoxen 1,2,3,4 ... meinen Spielfeldboxen zugeordnet

      Ab hier läuft dann vieles so wie bisher, außer das man die Subs jetzt mit _game.UserMove(...) aufruft. Da sie ja alle Mitglieder der Klasse sind.

      Soweit einiger maßen richtig???

      Dann noch ein paar kleinere Änderungen wir z.B.
      If CheckBoxBot.Checked = True then ...-> Besser, Eleganter If CheckBoxBot.Checked Then ...

      Ich hoffe ich hab die wichtigsten Punkte gesehen und einigermaßen verstanden.

      ALSO nochmal herzlichsten Dank für Deinen vielen Input!!!

      Ich bin immer noch auf der Suche nach einer Herangehensweise wie ich mein Verständnis für VB.Net effektiv verbessern kann. Ich hab mehrere 100 Seiten in in Rheinwerks Einstieg VB.net 2017 gelesen war auch hilfreich, aber ich hab das Gefühl das ich mich da auch viel durch blabla arbeiten muss um Sachen zu finden die gut sind. Vieles wird auch gar nicht behandelt wie z.B. eventArgs.
      Ideen?

      [color=rgb(33, 83, 146); font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; font-size: 14.98px; font-weight: 700; background-color: rgb(237, 244, 250)]Einstieg in Visual Basic 2012[/color]
      Erstmal. Für einen Anfänger hast Du das gar nicht schlecht gemacht, ehrlich nicht. Da hab ich schon von "Fortgeschrittenen" schlimmeres gesehen. Und Du hast, so wie es scheint, auch das Interesse, besser zu werden. Das haben viele andere nicht.

      zu 1.) ich meinte damit, ich habe die Änderungen mehr reingewurschelt, als dass es elegant wäre. Ich wollte eben Deinen Code nicht komplett umändern, sonst hättest Du das evtl. gar nicht nachvollziehen können. Das war auf die Änderungen bezogen, nicht generell auf Deinen Code.

      zu 2.) Die Dringlichkeit ist die, dass ein Aufruf wie Form1.xxx.xxx ein Relikt aus alten VB-Zeiten ist. Generell sollte man sich immer an der Sprache C# orientieren. Die Relikte sind nur aus Kompatiblitätsgründen noch in der Sprache VB.Net. In C# würde dieser Aufruf nicht funktionieren und das sollte Deine Motivation sein. Schon alleine für den Fall, dass Du irgendwann auf eine andere Sprache umsteigst. Dann stehst Du plötzlich da und weißt nicht weiter. Hier auch noch ein kleiner Artikel dazu. Visual Studio - Empfohlene Einstellungen

      zu 3.) Hier sind wir schon im Bereich von OOP. Eigentlich sollte die gesamte Spiele-Logik in diese Klasse ausgelagert sein. Du hast aber schon ganz gut verstanden, warum es dabei geht. Leider würde eine ausführliche Erklärung aller Aspekte den Rahmen hier sprengen. Es gab mal von Microsoft ein kostenloses E-Book, welches mir damals sehr geholfen hat. Leider wird dies wohl nicht mehr angeboten. Evtl. hat @ErfinderDesRades noch eine Kopie von ​Microsoft Visual Basic 2010 - Das Entwicklerbuch. Ich werde evtl. morgen mal meine alten Festplatten durchsuchen, irgendwo hab ich das auch noch. Ich kann Dir nur raten, einfach zu probieren und gezielt Fragen hier im Forum stellen. Lass auf jeden Fall vorerst Du Module weg.

      Du hast schon das Zeug, richtig gut zu werden. Du musst aber dran bleiben... Bei Fragen -> jederzeit.
      Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
      Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o

      How to turn OPTION STRICT ON
      Why OPTION STRICT ON
      @ SpaceyX Danke für die Blumen ^^
      "Für einen Anfänger hast Du das gar nicht schlecht gemacht, ehrlich nicht"
      :D Tut auch mal gut zu hören, dass man auf dem richtigen Weg ist und sich die Mühe zu lohnen scheint. In den letzten Wochen sind schon etliche Stunden für mein "neues" Hobby drauf gegangen. Deine Buchempfehlung hab ich für 16 € bei Ebay gebraucht geschossen, mal sehen, ob es für mich auch passt. Falls Du trotzdem eine Kopie auf HD findest, würde ich die trotz des Buches gerne auch benutzen.

      Hab deinen Link zu Visual Studio - Empfohlene Einstellungen nur kurz überflogen und mein erster Gedanke war .... solle ich doch gleich mit C# anfangen!!! Ich hatte mich eigentlich entschlossen nicht mehr darüber nachzugrübeln ob VB das richtige ist. Meine Denke war, ich mach VB erst mal intensiver und falls jemals der Punkt kommt, dass ich an Grenzen komme wo ich andere Sprachen brauche hoffe ich, dass ich dann aufgrund des VB Wissens schnell rein komme. Meinst Du das ich es später bereue nicht doch mit C# oder ganz was anderem begonnen zu haben? Schon klar das das eine Gretchen Frage ist aber trotzdem was ist den so dein Gefühl. VB der etwas leichtere Einstieg später neue Sprachen lernen ist schon okay oder neue Sprachen lernen ist dann doch nochmal ganz schön schwierig warum nicht gleich oder tue ich VB unrecht und die Sprache ist fast genau so "gut" wie C#. Sorry für die vielen Fragen

      @VaporiZed
      Falls ich Zeit finde, würde ich das TicTacoToe Project zu meinem ersten Project umschreiben wo ich dann Klassen // Objecte benutze. Danke für die Idee
      ​Stell Dir z.B. die Frage: Was wäre bei einem echten Spiel ein Objekt, was mit anderen interagiert?
      . Werde diesen Ansatz mal verfolgen bei meinen ersten Gehversuchen ...
      Das Entwicklerbuch ist bei MSPress erhältlich und im Thread vom Autor, Herrn Löffelmann, verlinkt. Neuere Versionen dürfen wir aber nicht selber hochladen, das Thema hatten wir vor ein paar Wochen schon mal.
      Naja, das mit "dann wechsel ich doch gleich auf C#" ist Deine Entscheidung. Es gibt ein paar Unterschiede in den Sprachen, aber ob Du einen Vortrag auf Englisch oder Französisch hältst, ist abhängig von Deinem Wissen und Deinem Wohlbefinden. Du kannst aber in beiden Sprachen es wohl alles so formulieren, dass es vom Zuhörer richtig verstanden wird. Der eine mag C#, der andere VB.Net. (Und viele, die beides nicht mögen).
      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.
      C# und VB.NET unterscheiden sich nicht viel. In VB hast Du eben ein paar Relikte, auf die Du aufpassen musst. Der Umstieg sollte keine große Hürde darstellen. Es geht vorerst darum, sich die grundlegenden Techniken anzueigen. Konzentriere Dich auf das und Du hast ein gutes Gerüst um später auf jede beliebige andere Sprache, die Dich interessiert, zu wechseln. Es gibt ja nicht nur die .NET-Welt. Ich habe es nie bereut, mit VB.NET begonnen zu haben und mache heute noch viel damit.
      Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
      Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o

      How to turn OPTION STRICT ON
      Why OPTION STRICT ON