PC-Gamer

  • VB.NET

Es gibt 29 Antworten in diesem Thema. Der letzte Beitrag () ist von silu.

    Hallo zusammen
    Ich bin neu hier und habe in der SuFu nicht gefunden was mir Hilft.
    Ich Progge ca seit 5 Monaten mit Viritual Basic 2010.
    Im mom bin ich am programmieren eins Spieles dazu brauche ich hilfe!
    beim Spiel Handelt es sich um ein Tic Tac Toe by Myself..also keine Youtubefakes sonder selber gemacht..=)
    habe vor 2 Tagen angefangen als Lernprojekt..=) also jetzt zu meinem Proplemmli

    Ich habe 9 Lables mit einem 0 oder X Player und eine Checkbox mit der ich einen PC-Gamer proggen will
    der PC-Gamer sollte bei cheked checkbox den 0 Player übernehmen.
    Meine Idee war mithilfe von randomizer den PC Bei Player 0 per zufall irgend eines der 9 labels zu clicken..
    allerdings haben alle meine versuche einen code zu schreiben nichts gebracht..
    deshalb wie kan ich das am besten schreiben??
    Warum haben deine Versuche das zu schreiben nichts gebracht, ist doch nicht so schwer?

    1. Ein ganz wichtiger Tipp: Trenne die innere Bearbeitung und die Ausgabe!
    Also arbeite nicht mit Labels, sondern mit internen Variablen. Die Labels sollen nur gut zur Ausgabe sein, und in deinem Fall auch die Eingabe machen.
    Aber teste bitte nicht : If Label.Text = "X" Then
    Duu_kannst_hier_nicht_mehr_klicken()
    End If

    ich hoffe du verstehst was ich meine...

    2. Eine KI in TicTacToe zu programmieren ist nicht so schwer, nur (wenn sie gut werden soll) einiges an Aufwand.

    Aber eine RandomSet Funktion ist leicht zu implementieren

    Einfach so lange eine Zahl zwische 1 und 9 generieren bis sie ein freies Feld trifft und dann dort setzen.

    Ich habe mal ein ganzes TicTacToe geschrieben, auch mit KI, das ist ganz ok geworden (glaub ich) :D

    mfG Nibel
    Nimm bitte nicht Randomize. Da wird bei jedem Programmstart eine identische Zahlenfolge erzeugt.
    Besser und einfacher ist die Random-Klasse. Mit Next(Int32, Int32) erzeugst du eine Zufallszahl im angegebenen Bereich (von Zahl1 bis Zahl2 - 1). Auf eines mußt du dabei allerdings achten. Deklariere das Random-Objekt nur einmal im Projekt global.
    Fiel Fergnügen
    Vatter
    :thumbsup: Seit 26.Mai 2012 Oppa! :thumbsup:
    Zunächst ein bisschen Pflichtlektüre:

    Forumsintern:
    [Allgemein] Entwickler-Ressourcen und Tools, Bücher und WebCasts
    [Allgemein] Grundlagen: Benennung von Controls (Update: 24.10.2010)
    [VB.NET] Beispiele für guten und schlechten Code (Stil)

    Galileo Openbooks:
    Galileo Openbook VB.NET
    Galileo Openbook Einstieg in VB 2008
    Galileo Openbook Einstieg in VB 2010

    Ein besserer Ansatz:

    0.

    Option Strict On

    1. Das Feld ist...

    leer
    X
    O

    also:

    VB.NET-Quellcode

    1. Private Enum FieldState
    2. Empty
    3. X
    4. O
    5. End Enum
    6. Dim field(2,2) As FieldState 'Das Spielfeld, 3x3 (0,0) bis (2,2) (Zeile, Spalte)


    2. Die Labels bekommen ANSTÄNDIGE Namen (siehe oben, Benennung von Controls)

    lblField<Zeile><Spalte> (z.B. lblField00 für Links oben, lblField20 rechts oben etc.)

    -EINEN Click-Handler, automatisiert erzeugt.

    VB.NET-Quellcode

    1. Private Sub FieldClick(ByVal sender As Object, ByVal e As EventArgs)
    2. Dim clicked As Label = DirectCast(sender, Label) 'Das geklickte Label
    3. 'Der code für das klicken eines Labels
    4. 'clicked.Name enthält hier lblField<Zeile><Spalte> des geklickten Felds.
    5. 'field(<Zeile>,<Spalte>) enthält den aktuellen Zustand des Felds
    6. CheckWins() 'Überprüft, ob emand einen Dreier hat bzw. unentschieden.
    7. End Sub


    VB.NET-Quellcode

    1. 'In der Form.Load:
    2. AddHandler lblField00.Click, AddressOf FieldClick
    3. 'Für ledes Label


    3. Die KI

    [vb]'... klickt keine Labels an, sondern arbeitet nur mit field(,) und CheckWins()



    Noch Fragen?
    ok ich danke für eure Antworten bin noch am tüfteln...
    noch wegen den labels mein code sieht bis jetzt so aus..
    natürlich habe ich Win sub etc auch schon ich habe das ganze programm fertig geproggt bis auf den pcgamer..

    VB.NET-Quellcode

    1. Public Class Form1
    2. Dim wert As Integer
    3. Private Sub playLabel1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles playLabel1.Click
    4. If turnplayerLabel.Text = "X" Then
    5. playLabel1.Text = "X"
    6. turnplayerLabel.Text = "0"
    7. Else
    8. playLabel1.Text = "0"
    9. turnplayerLabel.Text = "X"
    10. End If
    11. Call win()
    12. playLabel1.Enabled = False
    13. End Sub
    14. Private Sub playLabel2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles playLabel2.Click
    15. If turnplayerLabel.Text = "X" Then
    16. playLabel2.Text = "X"
    17. turnplayerLabel.Text = "0"
    18. Else
    19. playLabel2.Text = "0"
    20. turnplayerLabel.Text = "X"
    21. End If
    22. Call win()
    23. playLabel2.Enabled = False
    24. End Sub
    25. Private Sub playLabel3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles playLabel3.Click
    26. If turnplayerLabel.Text = "X" Then
    27. playLabel3.Text = "X"
    28. turnplayerLabel.Text = "0"
    29. Else
    30. playLabel3.Text = "0"
    31. turnplayerLabel.Text = "X"
    32. End If
    33. Call win()
    34. playLabel3.Enabled = False
    35. End Sub
    36. Private Sub playLabel4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles playLabel4.Click
    37. If turnplayerLabel.Text = "X" Then
    38. playLabel4.Text = "X"
    39. turnplayerLabel.Text = "0"
    40. Else
    41. playLabel4.Text = "0"
    42. turnplayerLabel.Text = "X"
    43. End If
    44. Call win()
    45. playLabel4.Enabled = False
    46. End Sub
    47. Private Sub playLabel5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles playLabel5.Click
    48. If turnplayerLabel.Text = "X" Then
    49. playLabel5.Text = "X"
    50. turnplayerLabel.Text = "0"
    51. Else
    52. playLabel5.Text = "0"
    53. turnplayerLabel.Text = "X"
    54. End If
    55. Call win()
    56. playLabel5.Enabled = False
    57. End Sub
    58. Private Sub playLabel6_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles playLabel6.Click
    59. If turnplayerLabel.Text = "X" Then
    60. playLabel6.Text = "X"
    61. turnplayerLabel.Text = "0"
    62. Else
    63. playLabel6.Text = "0"
    64. turnplayerLabel.Text = "X"
    65. End If
    66. Call win()
    67. playLabel6.Enabled = False
    68. End Sub
    69. Private Sub playLabel7_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles playLabel7.Click
    70. If turnplayerLabel.Text = "X" Then
    71. playLabel7.Text = "X"
    72. turnplayerLabel.Text = "0"
    73. Else
    74. playLabel7.Text = "0"
    75. turnplayerLabel.Text = "X"
    76. End If
    77. Call win()
    78. playLabel7.Enabled = False
    79. End Sub
    80. Private Sub playLabel8_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles playLabel8.Click
    81. If turnplayerLabel.Text = "X" Then
    82. playLabel8.Text = "X"
    83. turnplayerLabel.Text = "0"
    84. Else
    85. playLabel8.Text = "0"
    86. turnplayerLabel.Text = "X"
    87. End If
    88. Call win()
    89. playLabel8.Enabled = False
    90. End Sub
    91. Private Sub playLabel9_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles playLabel9.Click
    92. If turnplayerLabel.Text = "X" Then
    93. playLabel9.Text = "X"
    94. turnplayerLabel.Text = "0"
    95. Else
    96. playLabel9.Text = "0"
    97. turnplayerLabel.Text = "X"
    98. End If
    99. Call win()
    100. playLabel9.Enabled = False
    101. End Sub

    Vatter schrieb:

    Nimm bitte nicht Randomize. Da wird bei jedem Programmstart eine identische Zahlenfolge erzeugt.
    Besser und einfacher ist die Random-Klasse. Mit Next(Int32, Int32) erzeugst du eine Zufallszahl im angegebenen Bereich (von Zahl1 bis Zahl2 - 1). Auf eines mußt du dabei allerdings achten. Deklariere das Random-Objekt nur einmal im Projekt global.
    Fiel Fergnügen
    Vatter


    Hey Vatter, du hasz natürlich prinzipiell mit dem Hinweis auf die Randomklasse recht.
    Aber Randomize() erzeugt nicht jedesmal eine identische Zahlenfolge. Ganz im Gegenteil :)
    Randomize wird benötigt, um den Startseed für die Funktion Rnd() zu erzeugen. Dieser Seed wird aus dem System.Timer geholt.
    Daher ist Randomize der Randomizer der Funktion Rnd(). Diese erzeugt ohne ein Randomize() sonst immer die selben Zahlen.
    Das ist meine Signatur und sie wird wunderbar sein!
    @TS:

    Bitte packe lange Codes in

    Quellcode

    1. [expander][/expander]
    Blöcke.

    Des Weiteren solltest du dir meinen Ansatz ruhig mal durchlesen.
    Du siehst doch selbst die Redundanz deines Codes, oder?

    In meiner FieldClick kannst du den Status abfragen; wenn er nicht Empty ist, dann einfach keine Veränderung machen.
    Hier noch zur Ausgabe der Labels:

    VB.NET-Quellcode

    1. Private Sub DrawField()
    2. Dim tmpLbl As Label
    3. For row = 0 To 2
    4. For col = 0 To 2
    5. tmpLbl = Me.Controls("lbl" & row.ToString() & col.ToString())
    6. Select Case field(row, col)
    7. Case Empty
    8. tmpLbl.Text = ""
    9. Case X
    10. tmpLbl.Text = "X"
    11. Case O
    12. tmpLbl.Text = "O"
    13. End Select
    14. Next
    15. Next
    16. End Sub
    joop habs durchgelesen..=)
    ist mit sicherheit die bessere lösung als die die ich kreiert habe..=)
    aber zur entschuldigung..ich bin noch neuling und habe einfach mal so wild angefangen zu kreieren nachdem ich 1 buch angefangen habe zu lesen und alle 4 demos in VB gemacht habe..=)
    Ok ich will meinen code nich nochmal total überarbeiten da es ja wie gesagt ein übugsprogramm ist...
    eifentlich will ich nur noch diesen pcgamer fertigmachen und dan mit einem sauberen neuen projekt anfangen..=)
    also kan ich das auch so lösen..??


    Public Class Form1
    'ich sage dem pc das es sich um ein random handelt'
    Dim random As New Random
    danach ordne ich die 9 playlabels dem random zu und sage wen das hägli in der checkbox ist und Spieler 0 Dran ist soll mir VB irgend eines der 9 felder clicken

    ist das so möglich?? wen ja wie kan ich das random zu den labels zuordnen??
    sorry die fragen aber ich werde einfach im mom aus den Beschreibungen im buch nicht schlau..=(
    lol habe mir ein buch gekauft..ist aber nicht so der hammer das ding...
    macht mir ein grösseresdurcheinander als das programm selber..=)
    ok..werde nach neuem buch ausschau halten..und die openbook von link oben anschauen gehen..=)
    ..wie mache ich den das mit den perform clicks???
    thx für die hilfe

    FAtheone schrieb:

    Des Weiteren solltest du dir meinen Ansatz ruhig mal durchlesen.
    Du siehst doch selbst die Redundanz deines Codes, oder?
    Obwohl ein besserer Ansatz, bezweifle ich doch dass ein Neuling nach 6 Wochen schon viel mit AddHandler, DirectCast, ControlsCollection etc anfangen kann, ohne eine Menge Erklärungen dazu mitzugeben :rolleyes: Aber da es ein Lernprojekt ist, kann er ja alles in der nächsten Version besser machen. Ich glaube der wichtigste Hniweis überhaupt kam von Nibel: trenne die Präsentation der Daten von ihrer internen Darstellung ...

    silu schrieb:

    Dim random As New Random
    danach ordne ich die 9 playlabels dem random zu und sage wen das hägli in der checkbox ist und Spieler 0 Dran ist soll mir VB irgend eines der 9 felder clicken
    ist das so möglich?? wen ja wie kan ich das random zu den labels zuordnen??

    Dafür ist es nötig zu wissen, dass bestimmte Controls (Form, Panel, Groupbox, ...) als Container für andere Controls dienen können und man diese diese in ihrer .Controls Property abrufen kann. Diese kann man auch mit einer For...Each Schleife durchlaufen.

    Insofern solltest Du folgendes machen:
    - lege Dir eine leere Liste an dim emptyLabels as new List(of Control)
    - durchlaufe alle controls in der Form.Controls Collection und speichere die Label in der Liste ab die noch unbesetzt (leer) sind
    - ermittle eine Zufallszahl zwischen 0 und der Länge der Liste
    - wenn keine Elemente mehr frei sind so ist das Spiel zu Ende
    - simuliere einen Click mit .PerformClick

    Kommst Du mit diesen Hinweisen zurecht oder brauchst Du ein Beispiel ?

    Kangaroo schrieb:

    FAtheone schrieb:

    Des Weiteren solltest du dir meinen Ansatz ruhig mal durchlesen.
    Du siehst doch selbst die Redundanz deines Codes, oder?
    Obwohl ein besserer Ansatz, bezweifle ich doch dass ein Neuling nach 6 Wochen schon viel mit AddHandler, DirectCast, ControlsCollection etc anfangen kann, ohne eine Menge Erklärungen dazu mitzugeben :rolleyes: Aber da es ein Lernprojekt ist, kann er ja alles in der nächsten Version besser machen. Ich glaube der wichtigste Hniweis überhaupt kam von Nibel: trenne die Präsentation der Daten von ihrer internen Darstellung ...

    silu schrieb:

    Dim random As New Random
    danach ordne ich die 9 playlabels dem random zu und sage wen das hägli in der checkbox ist und Spieler 0 Dran ist soll mir VB irgend eines der 9 felder clicken
    ist das so möglich?? wen ja wie kan ich das random zu den labels zuordnen??

    Dafür ist es nötig zu wissen, dass bestimmte Controls (Form, Panel, Groupbox, ...) als Container für andere Controls dienen können und man diese diese in ihrer .Controls Property abrufen kann. Diese kann man auch mit einer For...Each Schleife durchlaufen.

    Insofern solltest Du folgendes machen:
    - lege Dir eine leere Liste an dim emptyLabels as new List(of Control)
    - durchlaufe alle controls in der Form.Controls Collection und speichere die Label in der Liste ab die noch unbesetzt (leer) sind
    - ermittle eine Zufallszahl zwischen 0 und der Länge der Liste
    - wenn keine Elemente mehr frei sind so ist das Spiel zu Ende
    - simuliere einen Click mit .PerformClick

    Kommst Du mit diesen Hinweisen zurecht oder brauchst Du ein Beispiel ?
    lol ja ich bin neuling und habe auch nicht viel zeit zum proggen..=) mache das so zwischendurch....bin zwar seit ca6 monaten dran habe etwa 6h zum proggen gebraucht bis jetzt..=)
    ja ein biespiel wäre sehr toll..=)
    Jetzt hat mich FAtheone natürlich extrem reingerissen: ein PerformClick gibt es zwar für Buttons aber dummerweise nicht für Labels. ;( Habe es jetzt im Beispiel mal über Reflection gelöst, ist aber ziemlich unschön :

    VB.NET-Quellcode

    1. ' im Kopf der Klasse angeben
    2. Dim r As New Random
    3. ...
    4. Sub randomLabelClick()
    5. ' leere control Liste anlegen
    6. Dim emptyLabels As New List(Of Control)
    7. ' alle controls der Form durchlaufen
    8. For Each c As Control In Me.Controls
    9. ' prüfe auf Name und unbesetzt -> füge zur liste hinzu
    10. If c.Name.StartsWith("playLabel") AndAlso c.Text = "" Then emptyLabels.Add(c)
    11. Next
    12. ' wenn liste leer -> keine freien Felder
    13. If emptyLabels.Count = 0 Then MessageBox.Show("keine freien Felder") : Return
    14. ' ermittle Zufallselement
    15. Dim i As Integer = r.Next(0, emptyLabels.Count) ' obere Grenze wird nie erreicht
    16. Dim randomCtrl As Control = emptyLabels(i)
    17. ' click per system.Reflection (sehr unschön)
    18. Dim onClickMethod As System.Reflection.MethodInfo = randomCtrl.GetType().GetMethod("OnClick", System.Reflection.BindingFlags.Instance Or System.Reflection.BindingFlags.NonPublic)
    19. onClickMethod.Invoke(randomCtrl, New Object() {Nothing})
    20. End Sub


    Sauberer wäre es für alle playLabels einen AddHandler zu setzten und dann nur die Methode aufzurufen um einen Click zu simulieren.
    ahhhhh f..........
    ich bringe es einfach nicht hin..
    habe jetzt auch mit dem gedanken gespielt per random eine zahl von 1-9 zu generieren und diese den labels zuzuordnen..
    ich krieg einfach keinen funktionierenden code hin!!
    also ich will das mit random machen..

    sollte dan irgendswie so sein

    Spieler 0 ist dran
    if turnplayerlabel.text = "0" then
    dan sollte mir random eine zahl zwischen 1-9 geben mit der sich das zugewiesene label klickt..=)
    l