  | 
					
						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: 06.01.2006 Beiträge: 2
 
  | 
		
			
				 Verfasst am: 29.10.2007, 00: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, 12: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: 06.01.2006 Beiträge: 2
 
  | 
		
			
				 Verfasst am: 29.10.2007, 14: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, 15: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.
  | 
   
 
     |