Problem mit berechnung verschiedener Dinge?

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

M0rgenstern

Betreff: Problem mit berechnung verschiedener Dinge?

BeitragSo, Feb 14, 2010 6:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Hey Leute.
Ich bin momentan im Zuge des BCC dabei Conway's Spiel des Lebens zu schreiben.
jetzt weiß ich allerdings nicht, ob ich das richtig verstanden habe, und vor allem ich hab irgendwoe ein Code Problem.
Er verfängt sich in irgendeiner Schleife und berechnet was, was er eigentlich nicht berechnen sollte.

Jede "Zelle" die "lebt" hat eine Nummer.
Und die Nummern werden halt immer wenn Zellen sterben neu verteilt.
Aber irgendwie rutscht er in den Minusbereich und scheint Zellen auf ein und der selbsen Stelle zu erstellen.
Das Problem ist, dass ich nicht genau weiß wo das Problem im Code liegen könnte, hab nur so ne wage Ahnung.

Jetzt weiß ich auch nicht, wie das aussieht, von wegen am BCC teilnehmen und sich hier helfen lassen.
Wenn das nicht gilt, dann werd ich für den Contest was anderes schreiben, aber dieses Programm würd ich schon gern umsetzen, einfach weil ichs total interessant finde.

Hier ist der komplette Code mal:

Code: [AUSKLAPPEN]
AppTitle "Game of Life BCC #35"

Graphics 800, 600, 32, 2
SetBuffer BackBuffer()

Const XGroesse = 20
Const YGroesse = 15
Dim SpielFeld(XGroesse,YGroesse)

Global FTimer = CreateTimer(50)

SeedRnd MilliSecs()

Type TCell
   Field XPos, YPos
   Field Red, Green, Blue
   Field Nr
   Field Dead
End Type

Global Nr = 0

SetCells()



Global ShowTimer = 1000
Global ShowStart = MilliSecs()



ClsColor 35, 35, 35

Cls
UpdateCells()
Flip 0

Repeat
   
   WaitTimer(FTimer)
   Cls
   
   
   For Zelle.TCell = Each TCell
      
      Color Zelle\Red, Zelle\Green, Zelle\Blue
      
      Oval Zelle\XPos, Zelle\Ypos, (GraphicsWidth()/XGroesse), (GraphicsHeight()/YGroesse), 1
      
      Color Zelle\Green, Zelle\Red, Zelle\Blue
      
      Text Zelle\XPos+5, Zelle\YPos+5, Zelle\Nr, 1, 1
      
   Next
   
   
   If ((ShowStart+ShowTimer) < MilliSecs()) Then
      CheckNeighbours()
      UpdateCells()
   EndIf
   
   
   Flip 0
   
Until KeyDown(1)


Function CheckNeighbours()
   Local indexa, indexb, Positionx, Positiony
   Local PosXUebergabe, PosYUebergabe
   Local XPos, YPos
   Local Anzahl = 0
   
   
   
   For indexa = 0 To (YGroesse-1)
      For indexb = 0 To (XGroesse-1)
         Anzahl = 0
         
         
         If (SpielFeld(indexb,indexa) = 1) Then
         
            For Positionx = 1 To -1 Step -1
               For Positiony = 1 To -1 Step -1
                  
                  PosXUebergabe = indexb - Positionx
                  PosYUebergabe = indexa - Positiony
                  
                  If ((PosXUebergabe >= 0) And (PosXUebergabe <= XGroesse)) Then
                     If ((PosYUebergabe >= 0) And (PosYUebergabe <= YGroesse)) Then
                        
                        If (SpielFeld(PosXUebergabe, PosYUebergabe) = 1) Then
                        
                           Anzahl = Anzahl + 1
                           
                        EndIf
                        
                     EndIf
                  EndIf
               Next
            Next
            
            For Zelle.Tcell = Each TCell
               If ((indexb = (Zelle\XPos/(GraphicsWidth()/XGroesse))) And (indexa = (Zelle\yPos/(GraphicsHeight()/YGroesse)))) Then
                  
                  If ((Anzahl = 2) Or (Anzahl = 3)) Then
                     
                     Zelle\Red = 65
                     Zelle\Green = 250
                     Zelle\Red = 65
                     
                  Else
                     
                     Zelle\Dead = 1
                     
                     Zelle\Red = 250
                     Zelle\Green = 65
                     Zelle\Blue = 65
                     
                  EndIf
               EndIf
            Next
            
         ElseIf (SpielFeld(indexb,indexa) = 0) Then
            
            For Positionx = 1 To -1 Step -1
               For Positiony = 1 To -1 Step -1
                  
                  PosXUebergabe = indexb - Positionx
                  PosYUebergabe = indexa - Positiony
                  
                  If ((PosXUebergabe >= 0) And (PosXUebergabe <= XGroesse)) Then
                     If ((PosYUebergabe >= 0) And (PosYUebergabe <= YGroesse)) Then
                        
                        If (SpielFeld(PosXUebergabe, PosYUebergabe) = 1) Then
                           
                           Anzahl = Anzahl + 1
                           
                        EndIf
                        
                     EndIf
                  EndIf
               Next
            Next
            
            If Anzahl = 3 Then
               
               Zelle.TCell = New TCell
               
               Nr = Nr + 1
               
               XPos = (indexb*(GraphicsWidth()/XGroesse))
               YPos = (indexa*(GraphicsHeight()/YGroesse))
               
               Zelle.TCell = New TCell
               Zelle\Xpos = XPos
               Zelle\YPos = YPos
               Zelle\Red = 250
               Zelle\Green = 65
               Zelle\Blue = 65
               Zelle\Nr = Nr
               Zelle\Dead = 0
               
            EndIf
                  
         
               
         EndIf
                  
         
      Next
   Next
   
   AppTitle "Anzahl: "+ Anzahl
   
   
   
   
End Function

Function UpdateCells()
   Local XPos, YPos
   ShowStart = MilliSecs()
   
   For Zelle.TCell = Each TCell
      
      If Zelle\Dead = 1 Then
         
         XPos = Zelle\XPos/(GraphicsWidth()/XGroesse)
         YPos = Zelle\YPos/(GraphicsHeight()/YGroesse)
         
         SpielFeld(XPos,YPos) = 0
         
         For Zelleb.TCell = Each TCell
            
            If Zelleb\Nr > Zelle\Nr Then Zelleb\Nr = Zelleb\Nr - 1
            Nr = Nr - 1
            
         Next
         
         Delete Zelle.TCell
         
      EndIf
      
      
   Next
   
End Function



Function SetCells()
   Local indexa, indexb, Zufallsetzen
   Local XPos, YPos
   
   For indexa = 0 To (YGroesse-1)
      For indexb = 0 To (XGroesse-1)
         
         Zufallsetzen = Rand(0,1)
         
         If Zufallsetzen = 1 Then
            
            SpielFeld(indexb,indexa) = 1
            
            Nr = Nr + 1
            
            XPos = (indexb*(GraphicsWidth()/XGroesse))
            YPos = (indexa*(GraphicsHeight()/YGroesse))
            
            Zelle.TCell = New TCell
            Zelle\Xpos = XPos
            Zelle\YPos = YPos
            Zelle\Red = 250
            Zelle\Green = 65
            Zelle\Blue = 65
            Zelle\Nr = Nr
            Zelle\Dead = 0
            
            i = 0
            
         EndIf
         
         
      Next
   Next
End Function


Und ich glaube, dass der Fehler in dieser Funktion liegt:

Code: [AUSKLAPPEN]
Function CheckNeighbours()
   Local indexa, indexb, Positionx, Positiony
   Local PosXUebergabe, PosYUebergabe
   Local XPos, YPos
   Local Anzahl = 0
   
   
   
   For indexa = 0 To (YGroesse-1)
      For indexb = 0 To (XGroesse-1)
         Anzahl = 0
         
         
         If (SpielFeld(indexb,indexa) = 1) Then
         
            For Positionx = 1 To -1 Step -1
               For Positiony = 1 To -1 Step -1
                  
                  PosXUebergabe = indexb - Positionx
                  PosYUebergabe = indexa - Positiony
                  
                  If ((PosXUebergabe >= 0) And (PosXUebergabe <= XGroesse)) Then
                     If ((PosYUebergabe >= 0) And (PosYUebergabe <= YGroesse)) Then
                        
                        If (SpielFeld(PosXUebergabe, PosYUebergabe) = 1) Then
                        
                           Anzahl = Anzahl + 1
                           
                        EndIf
                        
                     EndIf
                  EndIf
               Next
            Next
            
            For Zelle.Tcell = Each TCell
               If ((indexb = (Zelle\XPos/(GraphicsWidth()/XGroesse))) And (indexa = (Zelle\yPos/(GraphicsHeight()/YGroesse)))) Then
                  
                  If ((Anzahl = 2) Or (Anzahl = 3)) Then
                     
                     Zelle\Red = 65
                     Zelle\Green = 250
                     Zelle\Red = 65
                     
                  Else
                     
                     Zelle\Dead = 1
                     
                     Zelle\Red = 250
                     Zelle\Green = 65
                     Zelle\Blue = 65
                     
                  EndIf
               EndIf
            Next
            
         ElseIf (SpielFeld(indexb,indexa) = 0) Then
            
            For Positionx = 1 To -1 Step -1
               For Positiony = 1 To -1 Step -1
                  
                  PosXUebergabe = indexb - Positionx
                  PosYUebergabe = indexa - Positiony
                  
                  If ((PosXUebergabe >= 0) And (PosXUebergabe <= XGroesse)) Then
                     If ((PosYUebergabe >= 0) And (PosYUebergabe <= YGroesse)) Then
                        
                        If (SpielFeld(PosXUebergabe, PosYUebergabe) = 1) Then
                           
                           Anzahl = Anzahl + 1
                           
                        EndIf
                        
                     EndIf
                  EndIf
               Next
            Next
            
            If Anzahl = 3 Then
               
               Zelle.TCell = New TCell
               
               Nr = Nr + 1
               
               XPos = (indexb*(GraphicsWidth()/XGroesse))
               YPos = (indexa*(GraphicsHeight()/YGroesse))
               
               Zelle.TCell = New TCell
               Zelle\Xpos = XPos
               Zelle\YPos = YPos
               Zelle\Red = 250
               Zelle\Green = 65
               Zelle\Blue = 65
               Zelle\Nr = Nr
               Zelle\Dead = 0
               
            EndIf
                  
         
               
         EndIf
                  
         
      Next
   Next
   
   AppTitle "Anzahl: "+ Anzahl
   
   
   
   
End Function



Vielleicht kann mir ja jemand helfen.

Ist heute schon spät (oder früh, aber hab noch net geschlafen), also sorry wenn da nur Blödsinn steht.

Lg, M0rgenstern

EDIT:
Nochwas: Es "updated" das ganze dreimal wirklich sichtbar.
Danach verändern sich nur noch die Nummern der Zellen.

Xeres

Moderator

BeitragSo, Feb 14, 2010 7:16
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich verstehe dein System nicht so ganz. Wozu brauchst du Types? Zwei Arrays sollten doch ausreichen: Eines enthält 1 oder 0 - Lebendig/tot, das zweite die anzahl der lebenden Nachbarn für dieses Feld.
Oder so ähnlich.
Ganz ausnahmsweise halte ich Types da für fehl am platz Wink
Und wenn doch, dann definitiv mit dem Array verbunden:
Code: [AUSKLAPPEN]
Dim SpielFeld.TCell(XGroesse,YGroesse)
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Midimaster

BeitragSo, Feb 14, 2010 10:27
Antworten mit Zitat
Benutzer-Profile anzeigen
Sehr sonderbar ist dieser Dreizeiler:
BlitzBasic: [AUSKLAPPEN]
For Zelleb.TCell = Each TCell   
If Zelleb\Nr > Zelle\Nr Then Zelleb\Nr = Zelleb\Nr - 1
Nr = Nr - 1
Next

Was soll es?

Und das ist glaube ich auch unnötig:
BlitzBasic: [AUSKLAPPEN]
...
XPos = (indexb*(GraphicsWidth()/XGroesse))
YPos = (indexa*(GraphicsHeight()/YGroesse))

Zelle.TCell = New TCell
Zelle\Xpos = XPos
Zelle\YPos = YPos
....

Die Umrechnungen in echte Bildschirmkoordinaten und Speicherung in Zelle\Xpos...ist sinnlos, weil du sie an allen anderen Codestellen immer wieder zurückrechnest. Warum speicherst du nicht einfach nur IndexB...? Die Umrechnung in wahre Bildschirmkoordinaten ist eigentlich nur 1x beim Zeichnen nötig.

Außerdem fehlt glaube ich der Spielfeld()=1 bei der Geburt:
Zitat:
If Anzahl = 3 Then
Zelle.TCell = New TCell
Nr = Nr + 1
; hier fehlt was
XPos = (indexb*(GraphicsWidth()/XGroesse))
YPos = (indexa*(GraphicsHeight()/YGroesse))



BlitzBasic: [AUSKLAPPEN]
            If Anzahl = 3 Then                
Zelle.TCell = New TCell
Nr = Nr + 1

SpielFeld(indexb,indexa) = 1

XPos = (indexb*(GraphicsWidth()/XGroesse))
YPos = (indexa*(GraphicsHeight()/YGroesse))



Außerdem wirst du ganz schreckliche Performance-Probleme bekommen, weil vieles doppelt berechnet wird oder ganz unnötigt durchgeführt wird.

Die Anzahl-Berechnung bei CheckNeighbors() berechnest Du für den Fall
If (SpielFeld(indexb,indexa) = 1) Then
für jedes der Spielfelder und dann scannst du alle Zellen durch, um den betreffenden Stein zu finden . Das bremst das Programm tierisch aus. z.b. bei 3000 lebenden Zellen...macht 3000x3000=1 Mio Schleifendurchläufe. Hier wär es hilfreich, wenn du schon "wüßtest, welche Zelle an welcher Stelle steht.


so, das muss fürs erste reichen...

M0rgenstern

BeitragMo, Feb 15, 2010 13:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Hey, danke.
Ich habs jetzt komplett neu geschrieben nur mit nem Array.
Funktioniert prima und is auch viel schneller.

Vielen Dank.


Wie sieht das jetzt aus wegen der Teilnahme am BCC?

Lg, M0rgenstern

Xeres

Moderator

BeitragMo, Feb 15, 2010 14:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Was soll damit sein? Du hast hier kein komplettes Spiel gestellt bekommen und jeder kann vergleichen was du geleistet hast oder nicht und das ggf. in seine Bewertung einfließen lassen.
Würde mich btw. wundern, wenn es noch kein game of Life im Codearchiv gibt - aber es kommt ja immer auf konkrete Umsetzung an.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

M0rgenstern

BeitragMo, Feb 15, 2010 23:27
Antworten mit Zitat
Benutzer-Profile anzeigen
Okay.
Das ist gut zu wissen.
Danke.


Ich hab nur mal eine Frage:
Wie sehr gehen Arrays auf die Performance?
Bzw Zeichenbefehle wie "Oval"?
Ich hab nämlich gemerkt, dass ab über ca 900 Zellen das ganze etwas langsamer läuft.

Lg, M0rgenstern

Xeres

Moderator

BeitragMo, Feb 15, 2010 23:38
Antworten mit Zitat
Benutzer-Profile anzeigen
Zeichenbefehle werden im allgemeinen die Bremse sein. Ich weiß es nicht genau, aber die Rundungen bei Oval werden ziemlich rechenintensiv sein.
Male das doch einmal in ein Bild und zeige nur noch das an.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

M0rgenstern

BeitragMo, Feb 15, 2010 23:45
Antworten mit Zitat
Benutzer-Profile anzeigen
Sorry, aber wie genau du den letzten Satz meinst versteh ich nicht ganz.
Kannst du das bitte mal erklären, wie du das meinst?


Lg, M0rgenstern

jokerman29

BeitragMo, Feb 15, 2010 23:47
Antworten mit Zitat
Benutzer-Profile anzeigen
du sollst einfach über paint, gimp oder so den kreis oder dieses bild malen (nicht durch oval) und dann über loadimage laden. das spart rechenkapazitäten Wink
oder du zeichnest den kreis vorher und speicherst ihn in ein bild durch
BlitzBasic: [AUSKLAPPEN]
SaveImage
aber die 1. methode über paint ist einfacher
mfg
jokerman29

M0rgenstern

BeitragMo, Feb 15, 2010 23:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Das mit Paint geht nicht.
Ich hab das so gemacht, dass verschiedene Spielfeldgrößen wählbar sind.
Also muss dementsprechend auch jeweils der Kreis angepasst werden
Ich habs jetzt aber mal mit Rect versucht und das ist deutlich schneller.
Siht sogar besser aus, wie ich finde.

Werds dann so machen.

Vielen Dank.

Lg, M0rgenstern

Xeres

Moderator

BeitragMo, Feb 15, 2010 23:53
Antworten mit Zitat
Benutzer-Profile anzeigen
In dieser Reihenfolge:
CreateImage, SetBuffer, ImageBuffer, Oval Idea
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

M0rgenstern

BeitragMo, Feb 15, 2010 23:59
Antworten mit Zitat
Benutzer-Profile anzeigen
Achso. Okay.

Naja, wie gesagt.
Habs jetzt anders geregelt.

Vielen Dank.

Lg, M0rgenstern

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group