VisualBasic Ping Pong, Computer erwischt jeden Ball

  • Ersteller Ersteller GIHomer
  • Erstellt am Erstellt am
Status
Für weitere Antworten geschlossen.
G

GIHomer

Gast
Hey ho Leute,

von der Schule aus sollen wir ein Projekt machen jeder darf sich ein Spiel aussuchen und soll es programmieren, ich habe mich für "Pong" entschieden.

jetzt habe ich jedoch folgendes Problem das Programm läuft bis hier hin einwandfrei, jedoch erwischt der Computer jeden Ball was es unmöglich macht gegen Ihn zu gewinnen....

Hat vielleicht irgend jemand eine Idee wie ich den CPU dazu bringe mal einen Ball zu verfehlen ? Irgendwie das er für 1-2Sekunden stehen bleibt oder ähnliches ?

Code:
-------------------------------------------------------------------------------------------------
Public Class pongMain

Dim speed As Single = 20 ' Speed
Dim rndInst As New Random(0) ' Random
Dim xVel As Single = Math.Cos(rndInst.Next(5, 20)) * speed
Dim yVel As Single = Math.Sin(rndInst.Next(5, 20)) * speed

' Punkte
Dim compScore As Integer = 0
Dim plrScore As Integer = 0


Private Sub pongMain_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove

If e.Y > 5 And e.Y < Me.Height - 40 - paddlePlayer.Height Then _
paddlePlayer.Location = New Point(paddlePlayer.Location.X, e.Y)

End Sub

Private Sub gameTimer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles gameTimer.Tick


If gameBall.Location.Y > 5 And gameBall.Location.Y < Me.Height - 40 _
- paddlePlayer.Height Then _
paddleComputer.Location = New Point(paddleComputer.Location.X, gameBall.Location.Y)


gameBall.Location = New Point(gameBall.Location.X + xVel, gameBall.Location.Y + yVel)

' Obere Wand prüfen
If gameBall.Location.Y < 0 Then
gameBall.Location = New Point(gameBall.Location.X, 0)
yVel = -yVel
End If

' Untere Wand prüfen
If gameBall.Location.Y > Me.Height - gameBall.Size.Height - 45 Then
gameBall.Location = New Point(gameBall.Location.X, Me.Height - gameBall.Size.Height - 45)
yVel = -yVel

End If

' Spieler Paddle prüfen
If gameBall.Bounds.IntersectsWith(paddlePlayer.Bounds) Then
gameBall.Location = New Point(paddlePlayer.Location.X - gameBall.Size.Width, _
gameBall.Location.Y)
xVel = -xVel
End If


' Computer Paddle prüfen
If gameBall.Bounds.IntersectsWith(paddleComputer.Bounds) Then
gameBall.Location = New Point(paddleComputer.Location.X + paddleComputer.Size.Width + 1, _gameBall.Location.Y)
xVel = -xVel
End If


' Linke Wand prüfen
If gameBall.Location.X < 0 Then
plrScore += 1
gameBall.Location = New Point(Me.Size.Width / 2, Me.Size.Height / 2)
plrScoreDraw.Text = Convert.ToString(plrScore)
End If

' Rechte Wand prüfen
If gameBall.Location.X > Me.Width - gameBall.Size.Width - paddlePlayer.Width Then
compScore += 1
gameBall.Location = New Point(Me.Size.Width / 2, Me.Size.Height / 2)
compScoreDraw.Text = Convert.ToString(compScore)
End If



End Sub



Private Sub pongMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
: Windows.Forms.Cursor.Hide()
End Sub

Private Sub pongMain_SizeChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.SizeChanged
paddlePlayer.Location = New Point(Me.Width - 44, paddlePlayer.Location.Y)
plrScoreDraw.Location = New Point(Me.Width - 54, plrScoreDraw.Location.Y)
End Sub

Private Sub pongMain_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles MyBase.KeyPress






End Sub
End Class


-------------------------------------------------------------------------------------------------


Mit freundlichen Grüßen,
GIHomer:)
 
Ich kann zwar nicht programmieren, aber verlieren die Computerpong nicht einfach nur weil sie sich langsamer bewegen als ein diagonal geschlagener Ball?
 
Entweder du lässt ihn nur verzögert reagieren, oder du bringst einige Zufallsvariablen mit rein ;)
 
Das Problem ist halt, das sich der Computer Paddle immer genau auf der Höhe des Balles bewegt. Und immer exakt den Ball trifft dadurch :(
Ergänzung ()

@Götterwind
könntest du mir das mit der Zufallsvariable vielleicht erklären :D ?
 
spieler / computer bewegungsgeschwindigkeit verringern
und / oder ball geschwindigkeit erhöhen

wie wärs wenn der Computer erst reagiert sobald der Ball in seiner Hälfte des Spielfeldes ist?
 
paddleComputer.Location = New Point(paddleComputer.Location.X, gameBall.Location.Y)

Das ist der Fehler. Der Computer ist immer auf höhe des Balls. Schreib einen Code wo sich der Computer jeden Schritt nur einen bestimmten Wert in Richtung Ballhöhe nähert. Dann ist er für einige Bälle zu spät dran.

Edit: So in der Art:
if gameBall.Location.Y > paddleComputer.Location.Y then paddleComputer.Location.Y = paddleComputer.Location.Y + 5
else if gameBall.Location.Y < paddleComputer.Location.Y then paddleComputer.Location.Y = paddleComputer.Location.Y - 5
 
Ich kann zwar kein Visual Basic, kann dir deshalb nicht direkt mit Code helfen, aber kann dir rein von der Programmlogik her Ideen geben:
1. Gib dem Computer eine begrenzte Geschwindigkeit, mit der er sein Pad maximal bewegen darf. Abhängig davon, wie schnell dein Spiel läuft, kann das schon was ausmachen. Aber mach ihn nicht langsamer als du selbst dein Pad steuern kannst, das wäre "unrealistisch".
2. Lass den Computer ungenau sein. Da habe ich wieder mehrere Ideen:
2.1 Der Computer berechnet anhand der Flugbahn des Balls, wo er präzise auftrifft. Diesen Wert verrechnest du noch mit einer Zufallszahl, die eine kleine Abweichung ermöglicht. Beispiel: Der Computer errechnet, dass der Ball auf "Höhe 200" ankommt. Das Pad ist 50 Pixel hoch. Nun bestimmst du eine Zufallszahl von -30 bis +30, die du auf die errechnete Position aufrechnest. So verfehlt der Computer eventuell den Aufschlagsort, weil er sich "versteuert" hat.
2.2 Der Computer "wackelt" dauernd ein wenig. Damit dabei aber kein Blödsinn rauskommt, müsste man ihm definitiv noch eine gewisse Trägheit verpassen, damit die Bewegungen trotzdem einigermaßen geradlinig bleiben. Meiner Meinung nach ist dieser Ansatz schwerer zu realisieren als 2.1, da man über den 1. Punkt hinaus eine etwas komplexere Physik für das Pad einbauen müsste. 2.1 Harmoniert ziemlich gut mit 1., da hier schon die maximale Bewegungsgeschwindigkeit festgelegt ist und das Pad somit realistisch zur "erwarteten" Aufschlagsposition fliegen kann.

Derartige Denkansätze könnte man natürlich noch erheblich verfeinern um den Computer "menschlicher" spielen zu lassen, aber ich schätze das übersteigt eure Anforderungen erheblich. Ich würde es wirklich mit 1. und 2.1 versuchen, das dürfte, richtig umgesetzt, schon ganz nett aussehen. Genaue Werte für die Bewegungsgeschwindigkeit und Abweichungsberechnung musst du natürlich selbst rausfinden bzw. anpassen.
 
Dann muss sich das Paddle des Rechners eben nicht auf der Höhe des Balls bewegen, sondern nur in die Richtung der Höhe des Balls. Zudem gibts eine Höchstgeschwindigkeit des Paddles, die kleiner ist als die vertikale Geschwindigkeit eines Diagonal fliegenden Balls.
Ist doch gar nicht so schwer!?
 
GIHomer schrieb:
Das Problem ist halt, das sich der Computer Paddle immer genau auf der Höhe des Balles bewegt. Und immer exakt den Ball trifft dadurch :(
das musst du ändern:
Der Computer Spieler lässt sein "Paddle" immer da stehen, wo er gerade den Ball abgeblockt hat, erst wenn sich der Ball sagen wir in z.B. das linke Drittel bewegt reagiert der Computer-Spiele und berechnet, wo er das "Paddle" hinschieben muss.
Auch da wirst du wahrscheinlich noch Perfektion erreichen, je nachdem wie früh der Computerspieler reagieren darf (linkes drittel, viertel, fünftel) kann es aber schon durchaus passieren, dass wenn er von ganz unten nach ganz oben muss die Zeit dafür nicht ausreicht.

GIHomer schrieb:
könntest du mir das mit der Zufallsvariable vielleicht erklären :D ?
auf Basis meiner beschriebenen Änderung hast du einen menschlich wirkenderen Spieler, der möglicherweise immernoch perfekt spielt.
Nun nutzen wir eine Zufallsvariable um eine Fuzzy-KI zu implementieren: Wenn der Computer berechnet, wo er sein Paddle hinbewegen muss, baust du in die Formel eine Zufallsvariable ein (Formel musst du dir überlegen), die modifiziert wohin das Paddle bewegt wird.
Man könnte z.B. machen, dass der Computer in 80% der Fälle richtig liegt, aber in 20% der Fälle eine max. Abweichung von +- einem halben Paddle hat. Die reale Abweichung berechnest du dann durch eine Zufallsvariable von z.B. 30 bis 100 die den prozentualen realen Wert der max. Abweichung angibt, und noch per Zufall ob die Abweichung als positive oder negative Zahl genutzt wird.
Durch die Anpassung dieser beiden Größen (Wahrscheinlichkeit, max. Abweichung) kannst du dann durch Ausprobieren sogar verschiedene Schwierigkeitsstufen für eine KI implementieren ;)


Edit: mein Ansatz ist eine Mischung aus WickedWeazel und AP Nova, die in der Zwischenzeit gepostet haben (die Idee war aber unabhängig). Also schonmal 3 dumme mit 2 Gedanken:D
 
Zuletzt bearbeitet:
Sicher, dass du das selbst programmiert hast?
 
kk danke für eure Hilfen werde mal durchprobieren :D

nein selbstprogrammiert ist hier noch recht wenig, das ist alles ne Vorlage ala Google, als Grundlage.
Wird natürlich noch alles geändert und nicht so gelassen :)
 
kurz gesagt:

Der Ball muss in der Vertikalen schnellere Bewegungen machen als das Paddle der Spieler :)
Den Paddle der AI direkt auf die Y-Koordinate des Balles zu setzen ist natürlich der Auslöser deines Problemes.
 
Ich würde eine Reaktionsverzögerung, die durch eine zufällige Variablen festgelegt wird implementieren. Ab einer bestimmten größe dieser Variablen reicht es dann jeh nach entfernung zum Ball einfach nicht mehr, um den Ball zu erwischen. Damit spielt der Computer quasi immer noch perfekt reagiert aber hier und da nicht schnell genug. Somit wäre der Computerspieler auch unberechenbar, da man nie mit ein und dem selben Spielzug (winkel etc) gewinnen kann.
 
Hausaufgaben bitte selbst erledigen. Schon dreist, uns hier fremden Code als Eigenleistung zu verkaufen. :freak:
 
Status
Für weitere Antworten geschlossen.
Zurück
Oben