 |
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
BaLLeRTroeTe
Anmeldungsdatum: 07.01.2006 Beiträge: 2
|
Verfasst am: 29.10.2007, 01:03 Titel: Programm stürzt ab |
|
|
Habe vorhin aus Langeweilse angefangen, ein kleines spielchen zu programmieren.
Dabei sollen (nach dem bekannten Prinzip eben) die einzelnen Teile des Bildes so verschoben werden, dass das gesamte Bild wieder stimmt und rechts unten das schwarze Quadrat ist.
Da das Ganze innerhalb kurzer Zeit entstanden ist, ist es natürlich noch nicht optimiert/fertig und recht undurchschaubar - ich werde mich deshalb natürlich noch ans Verbessern machen
Nun zum eigentlichen Problem: Sobald ich das Puzzlestück rechts unten verschieben will, stürzt das Programm ab.
Dies ist auch so, wenn ich das schwarze Quadrat zB links oben hinsetze...
Ich kann den Fehler partout nicht finden, deshalb auch hier mein erster Post (man beachte das Anmeldedatum )
Compiler müsste 0.16b sein.
Code: | Screen 19,32
cls
Dim As String dateiname = "Puzzle.bmp", taste
Dim As Integer breit, hoch, ff = Freefile
Dim As Integer x, y, i, Richtung, Nummer, Richtige
Dim Shared Puzzelstueck(4,3, 160*160+2), Gemischt(4,3, 160*160+2)
Dim Shared As Integer XMouse, YMouse, Button
Dim Shared As Integer PuzzleX, PuzzleY
'-------------------------------------------------------------------------------
'Werte
'-------------------------------------------------------------------------------
PuzzleX = 79
PuzzleY = 59
'-------------------------------------------------------------------------------
'Bild laden
'-------------------------------------------------------------------------------
Open dateiname For Input As #ff
Get #ff, 19, breit
Get #ff, 23, hoch
Close #ff
Dim bild As Any Ptr
bild = ImageCreate(breit,hoch)
Bload dateiname, bild
Put (0,0), bild
i=1
For y = 0 To 2
For x = 0 to 3
Get (x*160, y*160)-Step(159, 159), Puzzelstueck(x+1,y+1,0)
Get (x*160, y*160)-Step(159, 159), Gemischt(x+1,y+1,0)
Puzzelstueck(x+1,y+1,25600)=i
Gemischt(x+1,y+1,25600)=i
i+=1
Next
Next
For Nummer = 0 to 25599
Puzzelstueck(4,3,Nummer) = 0
Gemischt(4,3,Nummer) = 0
Next
'-------------------------------------------------------------------------------
'Mischen
'-------------------------------------------------------------------------------
x=4
y=3
Randomize Timer
For i = 1 to 5
Richtung = Int(Rnd(1)*4)+1
Select Case Richtung
Case 1
If not x - 1 = 0 Then
For nummer = 0 To 25600
Swap Gemischt(x, y, nummer), Gemischt(x-1, y, nummer)
Next
x=x-1
Else
i = i - 1
End If
Case 2
If not y - 1 = 0 Then
For nummer = 0 To 25600
Swap Gemischt(x, y, nummer), Gemischt(x, y-1, nummer)
Next
y=y-1
Else
i = i - 1
End If
Case 3
If not x + 1 = 5 Then
For nummer = 0 To 25600
Swap Gemischt(x, y, nummer), Gemischt(x+1, y, nummer)
Next
x=x+1
Else
i = i - 1
End If
Case 4
If not y + 1 = 4 Then
For nummer = 0 To 25600
Swap Gemischt(x, y, nummer), Gemischt(x, y+1, nummer)
Next
y=y+1
Else
i = i - 1
End If
End Select
Next
Cls
'-------------------------------------------------------------------------------
'Puzzle ausgeben
'-------------------------------------------------------------------------------
For y = 0 to 2
For x = 0 to 3
Put (x*160 + PuzzleX, y*160 + PuzzleY), Gemischt(x+1,y+1,0), Pset
Next
Next
Line (PuzzleX - 1, PuzzleY - 1) - STEP(4*160+1, 3*160+1), RGB(255,255,255), b
'sleep
'-------------------------------------------------------------------------------
'Hauptschleife
'-------------------------------------------------------------------------------
Do
taste = inkey$:if taste = "q" then exit do 'Beenden, wenn q gedürckt wird
Getmouse XMouse, YMouse, , Button
Locate 1,0: Print x
Locate 2,0: Print y
Locate 3,0: Print XMouse
Locate 4,0: Print YMouse
Locate 5,0: Print Puzzelstueck(4,3,25600)
Locate 6,0: Print Richtige
If Button And XMouse > PuzzleX And XMouse < PuzzleX + 4*160+1 And YMouse > PuzzleY And YMouse < PuzzleY + 3*160+1 Then
x = XMouse - PuzzleX: y = YMouse - PuzzleY
x = int(X / 160) + 1: y = int(y / 160) + 1
If Gemischt(x + 1, y,25600) = 12 Then
For nummer = 0 To 25600
Swap Gemischt(x, y, nummer), Gemischt(x+1, y, nummer)
Next
End If
If Gemischt(x - 1, y,25600) = 12 Then
For nummer = 0 To 25600
Swap Gemischt(x, y, nummer), Gemischt(x-1, y, nummer)
Next
End If
If Gemischt(x, y + 1,25600) = 12 Then
For nummer = 0 To 25600
Swap Gemischt(x, y, nummer), Gemischt(x, y+1, nummer)
Next
End If
If Gemischt(x, y - 1,25600) = 12 Then
For nummer = 0 To 25600
Swap Gemischt(x, y, nummer), Gemischt(x, y-1, nummer)
Next
End If
'#------
cls
For y = 0 to 2
For x = 0 to 3
Put (x*160 + PuzzleX, y*160 + PuzzleY), Gemischt(x+1,y+1,0), Pset
Next
Next
Line (PuzzleX - 1, PuzzleY - 1) - STEP(4*160+1, 3*160+1), RGB(255,255,255), b
'------#
Richtige = 0
For y = 1 To 3
For x = 1 to 4
If Gemischt(x, y, 25600) = Puzzelstueck(x, y, 25600) Then Richtige += 1
Next
Next
If Richtige = 12 Then Print "Bärfekt": Sleep: End If
End If
Loop
|
Die Bilddateil ist eine BMP mit der Auflösung von 640*480. Theoretisch kann jede x-Beliebige genutzt werden, ich benutze testhalber dieses bild:
http://ballertroete.ba.funpic.de/Public/Puzzle.bmp
Falls sich jemand die Mühe machen würde, sich damit zu befassen, dann wäre ich demjenigen sehr dankbar - kann es aber auch verstehen, wenn sich das niemand antun will
Greetz, Stefan _________________ Diskutiere nie mit einem Idioten, denn er wird dich auf sein Niveau herunterziehen und dich dann mit erfahrung schlagen! |
|
Nach oben |
|
 |
croco97

Anmeldungsdatum: 04.11.2005 Beiträge: 260
|
Verfasst am: 29.10.2007, 13:25 Titel: |
|
|
Dir kann geholfen werden.
Kompilation fbc -g a.bas, Starten gdb a.exe und "r", Anklicken des re unteren Bildchens, dann erhalten wir:
Code: |
T:\h1>gdb a
GNU gdb 5.2.1
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i686-pc-mingw32"...
(gdb) r
Starting program: T:\h1/a.exe
Program received signal SIGSEGV, Segmentation fault.
0x00401bf6 in main (__FB_ARGC__=1, __FB_ARGV__=0xc43da0) at a.bas:150
150 IF Gemischt(x, y + 1,25600) = 12 THEN
(gdb)
|
Fehler ist also in Zeile 150. Schauen wir auf die Definition von Gemischt(), sehen wir, dass das dritte Argument unverdächtig ist, aber x und y sieht gefährlich aus. Schauen wir auf den ganzen Block, sehen wir, dass da hemmungslos auf x-1, x+1, y-1, y+1 zugegriffen wird, egal, ob sich der Block am Rand, in der Ecke oder sonstwo befindet, ggf. also gar kein "y-1" oder "y+1" definiert ist.
Zwei Kardinalfehler! Erstens die Arrayzugriffe in einer Methode (Sub / Function) kapseln, die generell den erlaubten Bereich überprüft.
Zweitens: Immer sich fragen, ob bei Indexzugriffen via "+etwas" oder "-etwas" nicht Ausnahmen auftreten können, bei denen "+etwas" oder "-minus" im Nirwana liegt.
Viele Grüsse!
Croco |
|
Nach oben |
|
 |
BaLLeRTroeTe
Anmeldungsdatum: 07.01.2006 Beiträge: 2
|
Verfasst am: 29.10.2007, 15:44 Titel: |
|
|
Vielen Dank
Der erlaubte Bereich wird schon überprüft:
Code: | IF Button AND XMouse > PuzzleX AND XMouse < PuzzleX + 4*160+1 AND YMouse > PuzzleY AND YMouse < PuzzleY + 3*160+1 |
Hier wird überprüft, ob der Mauszeiger im Bereich des Bildes liegt. Da die x- und y-Koordinaten aus den Mauskoordinatenhervorgehen, bin ich davon ausgegangen, dass da kein Fehler entstehen sollte.
Auf jeden Fall habe ich jetzt
Code: | DIM SHARED Puzzelstueck(4,3, 160*160+2), Gemischt(4,3, 160*160+2) |
zu
Code: | DIM SHARED Puzzelstueck(5,4, 160*160+2), Gemischt(5,4, 160*160+2) |
geändert, nun funktionierts  _________________ Diskutiere nie mit einem Idioten, denn er wird dich auf sein Niveau herunterziehen und dich dann mit erfahrung schlagen! |
|
Nach oben |
|
 |
croco97

Anmeldungsdatum: 04.11.2005 Beiträge: 260
|
Verfasst am: 29.10.2007, 16:05 Titel: |
|
|
Schon. Aber das ist gemogelt Ich hab jetzt keine Zeit, das weiter zu analysieren, aber x und y sind viel zu schlecht abgesichert. Sauberer Code würde so ausschauen:
Code: |
CONST puzzle_xmax=4
CONST puzzle_ymax=4
DIM SHARED gemischt(puzzle_xmax+1, puzzle_ymax+1,160*160+1)
(...)
if (x>=0 and x<=puzzle_xmax and y>=0 and y<=puzzle_ymax) then
(...)
else
' lab1
? "Error: Range overflow in gemischt() at lab1"
end if
(...)
|
Die Prüfung hat sich direkt auf den Index zu beziehen, nicht auf eine indirekte Ableitung "Wenn u = kompliziert (v), dann müsste x im richtigen Bereich liegen." Sowas geht garantiert schief.
Grüsse!
Croco |
|
Nach oben |
|
 |
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|