Problem mit berechnung verschiedener Dinge?
Übersicht

![]() |
M0rgensternBetreff: Problem mit berechnung verschiedener Dinge? |
![]() Antworten mit Zitat ![]() |
---|---|---|
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. |
||
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 ![]() 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 THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
Sehr sonderbar ist dieser Dreizeiler:
BlitzBasic: [AUSKLAPPEN] For Zelleb.TCell = Each TCell Was soll es? Und das ist glaube ich auch unnötig: BlitzBasic: [AUSKLAPPEN] ... 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 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 |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 |
||
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
![]() |
M0rgenstern |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 |
||
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
![]() |
M0rgenstern |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 ![]() oder du zeichnest den kreis vorher und speicherst ihn in ein bild durch BlitzBasic: [AUSKLAPPEN] SaveImageaber die 1. methode über paint ist einfacher mfg jokerman29 |
||
![]() |
M0rgenstern |
![]() Antworten mit Zitat ![]() |
---|---|---|
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 |
||
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
In dieser Reihenfolge:
CreateImage ![]() ![]() ![]() ![]() ![]() |
||
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 THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
![]() |
M0rgenstern |
![]() Antworten mit Zitat ![]() |
---|---|---|
Achso. Okay.
Naja, wie gesagt. Habs jetzt anders geregelt. Vielen Dank. Lg, M0rgenstern |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group