Programm stürzt unerklärbar ab
-
Hallo,
ich hab folgendes Problem, welches ich mir nicht erklären kann:
ich möchte mit rand() einen zufälligen x und y-Wert erzeugen. Danach soll geprüft werden, ob in der zweidemensionalen Matrix 'feld' der die Stelle [x][y] leer, also 0 ist. wenn ja, dann soll mit dem Programm fortgefahren werden, wenn nein soll, dann sollen x und y solange neu mit rand() 'berechnet' werden, bis 'feld' an der Stelle [x][y] 0 ist. Eigenlich eine simple Sache:do { x=rand()%(xbereich-1); y=rand()%(ybereich-1); } while(feld[x][y]!=leer);'xbereich' und 'ybereich' sind zuvor berechnete Variablen und begrenzen hier x und y. Leider klappt es nicht, das Programm bleibt hängen, noch bevor ein Fenster gezeigt wird. Das richtig abartige ist aber, dass es wo anders(WM_TIMER) im selben Code problemlos klappt! Auch das hier klappt:
x=rand()%(xbereich-1); y=rand()%(ybereich-1); if(feld[x][y]!=leer) { x=rand()%(xbereich-1); y=rand()%(ybereich-1); };Hat aber den Nachteil, dass die Wahrscheinlichkeit besteht, dass x/y trotzem auf eine Stelle zeigen, die besetzt ist. Übrigens: es liegt nicht daran, dass alle Stellen in 'feld' 'besetzt' sind, im Gegenteil, über 95% sind 0.
Wie kann das sein???



MfG Mark
-
Hi,
Also ich kann leider mit deiner Fehlerbeschreibung nicht viel anfangen. Was heist es bleibt hängen? Hast du irgendwelche Fehlerkontrollen? bist du dir sicher das deine Bedingung while(feld[x][y]!=leer); richtig ist?
Also so recht kann ich da jetzt nix erkennen.schirrmie
-
Also ich hab das auch einmal überprüft, wobei das immer zu einem ergebnis kommt.
int mat2D[100][100]; for(int i = 0; i < 100; i++) for(int ii = 0; ii < 100; ii++) mat2D[i][ii] = rand() % 2; int x, y; do { x = rand() % 99; y = rand() % 99; } while(mat2D[x][y]);
-
Hallo!
Erstmal drei Fragen dazu:
Wie ist die Matrix deklariert?
Wie wird sie initialisiert?
Ist die Anwendung Multithreaded?Grüsse
*this
-
Es kommt immer eine lösung obwohl ich in der Matrix etwa 50% 0 und 50% 1 habe.
Oder meinst du irgend etwas anderes als eine Dauerschleife?
-
schirrmie schrieb:
bist du dir sicher das deine Bedingung while(feld[x][y]!=leer); richtig ist?
Ja. 'leer' ist bei übrigens 0(mit #define definiert).
schirrmie schrieb:
Was heist es bleibt hängen?
Damit meine ich, dass das Programm auf garnichts reagiert und laut TaskManager die ganze freie CPU-leistung verbraucht.
Gast++ schrieb:
Wie ist die Matrix deklariert?
Wie wird sie initialisiert?
Ist die Anwendung Multithreaded?voaltile int feld[200][150]; ... for(x=0;x<200;x++) for(y=0;y<150;y++) feld[x][y]=leer;Nein, nur ein Thread.
Ich poste mal den ganzen Code. Leider ist er so ziemlich kommentarlos, weshalb ich ihn auch ungefähr erklären sollte:
Es ist ein Snakespiel. Man bewegt die schlange mit den Pfeiltasten zum grünen Kästchen uns sammelt es ein. Nachdem 'stonemax' Kästchen eingesammelt sind kommt das nächste Level. Ein Level besteht bei mir aus Linien, dessen verhältinismäßige Anfangs- und Endpositionen in einem int-array deklariert sind. So kann das Fenster in der Größe problemlos geändert werden. Das meiste läuft in WM_TIMER ab. Die Funktion NewGame(HWND) leert das Spielfeld, erzeugt aus dem entsperechenden Levelarray ein Raster, welches in die Var feld geschrieben wird. Die Funktion FeldLine(x1,y1,x2,y2) zeichnet eine Wand ins 'feld'. Zusätlich gibt es Steine, die die Schlange an einen anderen Ort 'teleportieren'. Das Problem liegt in Zeile 773 in der NewGame() beim erzeugen der Zufallsposition für den ersten einzusammelnden Stein. Die Erzeugung der nächsten Steine liegt in Zeile 549, nämlich dann, wenn ein bereits exestierender Stein eingessammelt wird und ein neuer hinmuss. Da klappt die do...while-Methode problemlos. Der Compiler ist überigens GCC mit DEV-C++.
...
Äh wie fügt man hier Dateien ein???
MfG Mark
-
Du kannst ja mal versuchen den ganzen Code in einen Code-Block eingefügt zu posten(dauert sicher nicht lang
). Hat Dev-C++ einen Debugger? Dann könntest du an der richtigen stelle halten und genau nachgucken wo es hängt.
-
Snake.cpp:
#include <windows.h> #include <time.h> //für rand() #include "resource.h" #define leer 0 //für eine leere stelle #define schlange 1 //da ist ein teil der schlange #define stein 2 //da ist ein stein zum einsammeln #define wand 3 //da ist eine Wand #define trans 4 //da liegt ein 'transformer' zum teleportieren #define stonemax 5 //anzahl der steine zum nachsten level #define SnakeTimer 1 //TIMER-ID für den timer der schlange #define SnakeColor RGB(150, 0, 255) //farbe der schlange #define levels 7 //anzahl der levels HDC hdc; PAINTSTRUCT ps; HBRUSH hBrush; volatile int SnakeSpeed; //für den timer in ms volatile int feld[200][150]; //da ist der gesamte inhalt des spielfelds enthalten volatile int translistx[32],translisty[32];//liste für die transformer, von wo nach wohin volatile int xbereich,ybereich; //aktiver bereich, in der WM_SIZE berechnet volatile int toadd,lengh;//toadd: anzahl der steine, die noch dazu addiert werden müssen // wenn die schlange einen stein einsammelt, wird dann bis 0 runtergezählt //lengh: aktuelle länge der schlange volatile int xbuff[256],ybuff[256];//buffer für die position der einzelnen schlangenkästchen, //[0] ist das letzte volatile int xpos,ypos,xv,yv;//aktuelle position der schlange so wie die richtung, //werden bei WM_TIMER zusammenaddiert volatile int pause;//1=pause,0=aktives spiel volatile int levelcount;//nummer des aktuellen levels volatile int stonecount;//anzahl der eingesammelten steine volatile int minimized;//1 wenn das fenster bei der letzten WM_SIZE minimiert wurde volatile int killoncrash;//1: schalnge wird beim crash sofort getötet, //0: schlange wird stückweise abgeschnitten volatile int transer;//anzahl der transformer im aktueleln level /* Declare Windows procedure */ LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); void NewGame(HWND hwnd); void FeldLine(unsigned char x1,unsigned char y1,unsigned char x2,unsigned char y2); /* Make the class name into a global variable */ char szClassName[ ] = "MorkSnake"; const char szInfo[]=" Snake V1.6\n\n" "Steurung: Pfeiltasten zum Bewegen\n" "'P' für Pause\n\n" "Ziel: Einsammeln von grünen Punkten,\n" "um in den nächsten Level zu kommen\n\n" " Viel Spaß!\n\n"; //die levels int level1[]={ //startposition 500,500, //anzahl der linien: //0 ist dabei ganzlinks bzw oben, 1000 ganz rechts/unten im fenster //500 ist demanch die mmitte 2, //Linien: 250,250,250,750, 750,250,750,750, //Amzahl Transformer 0 //dessen Pos: }; int level2[]={ //startposition 500,500, //anzahl der linien: 8, //Linien: x1,y1,x2,y1 //0 ist dabei ganzlinks bzw oben, 1000 ganz rechts/unten im fenster //500 ist demanch die mmitte 160,160,330,160, 160,160,160,330, 670,160,830,160, 830,160,830,330, 160,670,160,830, 160,830,330,830, 670,830,830,830, 830,670,830,830, //Amzahl Transformer 0 //dessen Pos: }; int level3[]={ //startposition 500,500, //anzahl der linien: //0 ist dabei ganzlinks bzw oben, 1000 ganz rechts/unten im fenster //500 ist demanch die mmitte 4, //Linien: 200,200,800,200, 200,200,200,800, 200,800,800,800, 800,200,800,800, //Amzahl Transformer 2, //dessen Pos: 300,300,900,900, 900,900,300,300 }; int level4[]={ //startposition 500,200, //anzahl der linien: //0 ist dabei ganzlinks bzw oben, 1000 ganz rechts/unten im fenster //500 ist demanch die mmitte 14, //Linien: 0,0,200,0, 300,0,700,0, 800,0,1000,0, 1000,0,1000,200, 1000,300,1000,700, 1000,800,1000,1000, 1000,1000,800,1000, 700,1000,300,1000, 200,1000,0,1000, 0,1000,0,800, 0,700,0,300, 0,200,0,0, 300,500,700,500, 500,300,500,700, //Amzahl Transformer 0 //dessen Pos: }; int level5[]={ //startposition 200,200, //anzahl der linien: //0 ist dabei ganzlinks bzw oben, 1000 ganz rechts/unten im fenster //500 ist demanch die mmitte 10, //Linien: 500,0,500,1000, 0,500,1000,500, 100,100,400,100, 100,100,100,400, 600,100,900,100, 900,100,900,400, 100,600,100,900, 100,900,400,900, 600,900,900,900, 900,900,900,600, //Amzahl Transformer 0 //dessen Pos: }; int level6[]={ //startposition 500,500, //anzahl der linien: //0 ist dabei ganzlinks bzw oben, 1000 ganz rechts/unten im fenster //500 ist demanch die mmitte 16, //Linien: 100,100,400,100, 100,100,100,400, 400,100,400,400, 100,400,400,400, 600,100,900,100, 600,100,600,400, 900,100,900,400, 600,400,900,400, 100,600,400,600, 100,600,100,900, 400,600,400,900, 100,900,400,900, 600,600,900,600, 600,600,600,900, 900,600,900,900, 600,900,900,900, //Amzahl Transformer 8, //dessen Pos: 475,475,250,250, 250,250,475,475, 525,475,750,250, 750,250,525,475, 475,525,250,750, 250,750,475,525, 525,525,750,750, 750,750,525,525 }; int level7[]={ //startposition 200,200, //anzahl der linien: //0 ist dabei ganzlinks bzw oben, 1000 ganz rechts/unten im fenster //500 ist demanch die mmitte 6, //Linien: 0,0,1000,0, 0,0,0,1000, 1000,0,1000,1000, 0,1000,1000,1000, 500,0,500,1000, 0,500,1000,500, //Amzahl Transformer 4, //dessen Pos: 250,250,750,250, 750,250,250,750, 250,750,750,750, 750,750,250,250 }; //das level-zeiger-array int*level[]={level1,level2,level3,level4,level5,level6,level7}; //standart winmain int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil) { HWND hwnd; /* This is the handle for our window */ MSG messages; /* Here messages to the application are saved */ WNDCLASSEX wincl; /* Data structure for the windowclass */ HACCEL hAccel; /* The Window structure */ wincl.hInstance = hThisInstance; wincl.lpszClassName = szClassName; wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */ wincl.style = CS_DBLCLKS; /* Catch double-clicks */ wincl.cbSize = sizeof (WNDCLASSEX); /* Use default icon and mouse-pointer */ wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION); wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); wincl.hCursor = LoadCursor (NULL, IDC_ARROW); wincl.lpszMenuName = "UNSERMENU"; /* No menu */ wincl.cbClsExtra = 0; /* No extra bytes after the window class */ wincl.cbWndExtra = 0; /* structure or the window instance */ /* Use Windows's default color as the background of the window */ wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND; /* Register the window class, and if it fails quit the program */ if (!RegisterClassEx (&wincl)) return 0; /* The class is registered, let's create the program*/ hwnd = CreateWindowEx ( 0, /* Extended possibilites for variation */ szClassName, /* Classname */ "MorkSnake V1.6", /* Title Text */ WS_OVERLAPPEDWINDOW, /* default window */ CW_USEDEFAULT, /* Windows decides the position */ CW_USEDEFAULT, /* where the window ends up on the screen */ 544, /* The programs width */ 425, /* and height in pixels */ HWND_DESKTOP, /* The window is a child-window to desktop */ NULL, /* No menu */ hThisInstance, /* Program Instance handler */ NULL /* No Window Creation data */ ); /* Make the window visible on the screen */ ShowWindow (hwnd, nFunsterStil); hAccel = LoadAccelerators(hThisInstance, "SHORTCUTS"); /* Run the message loop. It will run until GetMessage() returns 0 */ while (GetMessage (&messages, NULL, 0, 0)) { if(!TranslateAccelerator(hwnd, hAccel, &messages)) { /* Translate virtual-key messages into character messages */ TranslateMessage(&messages); /* Send message to WindowProcedure */ DispatchMessage(&messages); } } /* The program return-value is 0 - The value that PostQuitMessage() gave */ return messages.wParam; } /* This function is called by the Windows function DispatchMessage() */ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { int i,x,y;// Variablen zur zzwischenberechnung char c[10]; switch (message) /* handle the messages */ { //defaultwerte einstellen und spiel beginnen case WM_CREATE: SnakeSpeed=64; levelcount=0; killoncrash=0; srand( (unsigned)time( NULL ) ); NewGame(hwnd); return 0; //x- und ybereich neu berechnen, wenn größe geändert case WM_SIZE: xbereich = (LOWORD(lParam)-8)/8+1; ybereich = (HIWORD(lParam)-8-16)/8+1; //16 für den Status if(HIWORD(lParam)==0)//minimiert { minimized=1; KillTimer(hwnd,SnakeTimer); } else if(minimized==1)//maximiert { minimized=0; pause=1; hdc=GetDC(hwnd); TextOut(hdc,0,ybereich*8,"Game paused",11); ReleaseDC(hwnd,hdc); } else NewGame(hwnd);//größe geändert->die wände neu berechnen return 0; //wenn fenster (de)aktiviert case WM_ACTIVATE: if (!LOWORD(wParam)) { pause=1; KillTimer(hwnd,SnakeTimer); hdc=GetDC(hwnd); TextOut(hdc,0,ybereich*8,"Game paused",11); ReleaseDC(hwnd,hdc); }; return 0; //zeichenet den anwendungsberecih neu case WM_PAINT: hdc = BeginPaint(hwnd, &ps); //ein rechteck, damit man sieht, wo die grenzen sind Rectangle(hdc,0,0,xbereich*8-1,ybereich*8-1); for(x=0;x<xbereich;x++)//ganzes feld scannen for(y=0;y<ybereich;y++) if(feld[x][y]==schlange)//blaues kästchen { hBrush = (HBRUSH) SelectObject(hdc,CreateSolidBrush(SnakeColor)); Rectangle(hdc,x*8,y*8,x*8+7,y*8+7); DeleteObject(SelectObject(hdc, hBrush)); } else if(feld[x][y]==wand)//schwarzes kästchen { hBrush = (HBRUSH) SelectObject(hdc,CreateSolidBrush(RGB(0, 0, 0))); Rectangle(hdc,x*8,y*8,x*8+7,y*8+7); DeleteObject(SelectObject(hdc, hBrush)); } else if(feld[x][y]==trans)//rostes kästchen { hBrush = (HBRUSH) SelectObject(hdc,CreateSolidBrush(RGB(255, 0, 0))); Rectangle(hdc,x*8,y*8,x*8+7,y*8+7); DeleteObject(SelectObject(hdc, hBrush)); } else if(feld[x][y]==stein)//grünes kästchen { hBrush = (HBRUSH) SelectObject(hdc,CreateSolidBrush(RGB(0, 255, 0))); Rectangle(hdc,x*8,y*8,x*8+7,y*8+7); DeleteObject(SelectObject(hdc, hBrush)); }; if(pause)TextOut(hdc,0,ybereich*8,"Game paused",11); //anzahl der noch einzusammelnder steine itoa(stonemax-stonecount,c,10); TextOut(hdc,xbereich*8-50,ybereich*8,c,strlen(c)); for(i=0;i<6-strlen(c)*2;i++) TextOut(hdc,(xbereich*8-42)+i*4,ybereich*8," ",1); TextOut(hdc,(xbereich*8-90),ybereich*8,"Noch ",6); EndPaint(hwnd, &ps); return 0; //die richtungsvariablen xv/yv ändern bzw spiel püausieren/aktivieren case WM_KEYDOWN: switch(wParam) { case VK_UP: if(yv!=1) { yv=-1; xv=0; }; return 0; case VK_DOWN: if(yv!=-1) { yv=1; xv=0; }; return 0; case VK_RIGHT: if(xv!=-1) { yv=0; xv=1; }; return 0; case VK_LEFT: if(xv!=1) { yv=0; xv=-1; }; return 0; case 'P': if(pause) { pause=0; SetTimer(hwnd,SnakeTimer,SnakeSpeed,NULL); RECT rc; rc.left=0; rc.top=ybereich*8; rc.right=150; rc.bottom=ybereich*8+16; InvalidateRect(hwnd,&rc,TRUE); } else { pause=1; KillTimer(hwnd,SnakeTimer); hdc=GetDC(hwnd); TextOut(hdc,0,ybereich*8,"Game paused",11); ReleaseDC(hwnd,hdc); }; return 0; case VK_F1: pause=1; hdc=GetDC(hwnd); TextOut(hdc,0,ybereich*8,"Game paused",11); ReleaseDC(hwnd,hdc); KillTimer(hwnd,SnakeTimer); MessageBox(hwnd,szInfo,"Info",MB_ICONINFORMATION | MB_OK); return 0; case VK_F2: levelcount=0; NewGame(hwnd); return 0; case VK_F3: NewGame(hwnd); return 0; //geschwndigkeit ändern case '1': SnakeSpeed=256; SetTimer(hwnd,SnakeTimer,SnakeSpeed,NULL); return 0; case '2': SnakeSpeed=128; SetTimer(hwnd,SnakeTimer,SnakeSpeed,NULL); return 0; case '3': SnakeSpeed=64; SetTimer(hwnd,SnakeTimer,SnakeSpeed,NULL); return 0; case '4': SnakeSpeed=32; SetTimer(hwnd,SnakeTimer,SnakeSpeed,NULL); return 0; case '5': SnakeSpeed=16; SetTimer(hwnd,SnakeTimer,SnakeSpeed,NULL); return 0; case '6': SnakeSpeed=8; SetTimer(hwnd,SnakeTimer,SnakeSpeed,NULL); return 0; }; return 0; //das eigentliche spiel case WM_TIMER: if(toadd)//wenn die schlange verlängert werden soll { toadd--; lengh++; } else//ansonsten letztes kästchen löschen und positionsFIFO um eins shiften { if(feld[*xbuff][*ybuff]!=trans) { RECT rc; rc.left=xbuff[0]*8; rc.top=ybuff[0]*8; rc.right=xbuff[0]*8+7; rc.bottom=ybuff[0]*8+7; feld[xbuff[0]][ybuff[0]]=leer; InvalidateRect(hwnd,&rc,TRUE); }; for(i=0;i<lengh;i++) { xbuff[i]=xbuff[i+1]; ybuff[i]=ybuff[i+1]; }; }; //berechnen der neuen position anhand von xv/yv xpos+=xv; ypos+=yv; if(xpos>xbereich-1)xpos=0;//gucken, ob die schlange ausserhalbs des feldes liegt else if(xpos<0)xpos=xbereich-1; if(ypos>ybereich-1)ypos=0; else if(ypos<0)ypos=ybereich-1; switch(feld[xpos][ypos])//gtucken, was an der stelle ist { case stein: //wen nein stein dann einsammeln, toadd erhöhen und einen neuen stein erzeugen feld[xpos][ypos]=schlange; toadd+=3; //zufallskoordinaten erzeugen,klappt perfekt do { x=rand()%(xbereich-1); y=rand()%(ybereich-1); } while(feld[x][y]!=leer); hdc=GetDC(hwnd); hBrush = (HBRUSH) SelectObject(hdc,CreateSolidBrush(RGB(0, 255, 0))); Rectangle(hdc,x*8,y*8,x*8+7,y*8+7); DeleteObject(SelectObject(hdc, hBrush)); feld[x][y]=stein; stonecount++; //anzahl der einzusammelnder steine ausgeben itoa(stonemax-stonecount,c,10); TextOut(hdc,xbereich*8-50,ybereich*8,c,strlen(c)); for(i=0;i<6-strlen(c)*2;i++) TextOut(hdc,(xbereich*8-42)+i*4,ybereich*8," ",1); ReleaseDC(hwnd,hdc); if(stonecount>=stonemax)//wenn genug steine->nächstes level { levelcount++; NewGame(hwnd); return 0; }; //nein, kein break|return !!! //jetzt den positionsFIFO mit ankueller position beschreiben und ein neues //kästchen zeichnen case leer: feld[xpos][ypos]=schlange; xbuff[lengh]=xpos; ybuff[lengh]=ypos; hdc=GetDC(hwnd); hBrush = (HBRUSH) SelectObject(hdc,CreateSolidBrush(SnakeColor)); Rectangle(hdc,xpos*8,ypos*8,xpos*8+7,ypos*8+7); DeleteObject(SelectObject(hdc, hBrush)); ReleaseDC(hwnd,hdc); return 0; case trans://wenn trasformer for(i=0;i<(transer);i++)//suchen nach der postion in der liste { if((xpos==translistx[i*2])&&(ypos==translisty[i*2])) { xpos=translistx[i*2+1];//teleportieren ypos=translisty[i*2+1]; xbuff[lengh]=xpos; ybuff[lengh]=ypos; return 0; }//von der V1.5: /*else if((xpos==translistx[i*2+1])&&(ypos==translisty[i*2+1])) { xpos=translistx[i*2]; ypos=translisty[i*2]; xbuff[lengh]=xpos; ybuff[lengh]=ypos; return 0; }*/; }; return 0; default://ansonsten: if(killoncrash)//wenn killoncrash dann level neustarten NewGame(hwnd); else//sonst schlange kürzen { lengh--; if(lengh>0) { xpos-=xv; ypos-=yv; } else NewGame(hwnd); }; return 0; }; return 0; case WM_COMMAND://menüpunkte und tastaturkürzel switch(LOWORD(wParam)) { case IDM_NEU: levelcount=0; case IDM_RESET: NewGame(hwnd); return 0; case IDM_BEENDEN: pause=1; hdc=GetDC(hwnd); TextOut(hdc,0,ybereich*8,"Game paused",11); ReleaseDC(hwnd,hdc); KillTimer(hwnd,SnakeTimer); int mes; KillTimer(hwnd,SnakeTimer); mes=MessageBox(hwnd,"Wirklich Beenden?","Beenden",MB_OKCANCEL); if(mes==IDOK) PostQuitMessage (0); /* send a WM_QUIT to the message queue */ return 0; case IDM_VERYSLOW: SnakeSpeed=256; SetTimer(hwnd,SnakeTimer,SnakeSpeed,NULL); return 0; case IDM_SLOW: SnakeSpeed=128; SetTimer(hwnd,SnakeTimer,SnakeSpeed,NULL); return 0; case IDM_NORMAL: SnakeSpeed=64; SetTimer(hwnd,SnakeTimer,SnakeSpeed,NULL); return 0; case IDM_FAST: SnakeSpeed=32; SetTimer(hwnd,SnakeTimer,SnakeSpeed,NULL); return 0; case IDM_VERYFAST: SnakeSpeed=16; SetTimer(hwnd,SnakeTimer,SnakeSpeed,NULL); return 0; case IDM_EXTFAST: SnakeSpeed=8; SetTimer(hwnd,SnakeTimer,SnakeSpeed,NULL); return 0; case IDM_INFO: pause=1; hdc=GetDC(hwnd); TextOut(hdc,0,ybereich*8,"Game paused",11); ReleaseDC(hwnd,hdc); KillTimer(hwnd,SnakeTimer); MessageBox(hwnd,szInfo,"Info",MB_ICONINFORMATION | MB_OK); return 0; case IDM_KILLY: killoncrash=1; return 0; case IDM_KILLN: killoncrash=0; return 0; }; case WM_DESTROY: PostQuitMessage (0); /* send a WM_QUIT to the message queue */ break; default: /* for messages that we don't deal with */ return DefWindowProc (hwnd, message, wParam, lParam); } return 0; } //initialsiert den level void NewGame(HWND hwnd) { int i,imax,x,y; int* plevel; for(x=0;x<200;x++)//feld leeren for(y=0;y<150;y++) feld[x][y]=leer; lengh=1;//startlänge:1 toadd=5;//soll dan auf 6 erhöht werden xv=1;//startrichtung;nach rechts yv=0; stonecount=0; pause=0; if(levelcount>=levels)levelcount=0;//beim überlauf wieder auf level 0 plevel=level[levelcount];//pointer initialsieren xpos=(xbereich-1)*plevel[0]/1000;//startpunkt holen ypos=(ybereich-1)*plevel[1]/1000; xbuff[0]=xpos; ybuff[0]=ypos; feld[xpos][ypos]=schlange; imax=plevel[2]; plevel+=3; for(i=0;i<imax;i++)//wände zeichnen { FeldLine((xbereich-1)*plevel[0]/1000,(ybereich-1)*plevel[1]/1000,(xbereich-1)*plevel[2]/1000,(ybereich-1)*plevel[3]/1000); plevel+=4; }; imax=*plevel; transer=imax; plevel++; for(i=0;i<imax;i++)//transformer setzen { feld[(xbereich-1)*plevel[0]/1000][(ybereich-1)*plevel[1]/1000]=trans; feld[(xbereich-1)*plevel[2]/1000][(ybereich-1)*plevel[3]/1000]=trans; translistx[i*2]=(xbereich-1)*plevel[0]/1000; translistx[i*2+1]=(xbereich-1)*plevel[2]/1000; translisty[i*2]=(ybereich-1)*plevel[1]/1000; translisty[i*2+1]=(ybereich-1)*plevel[3]/1000; plevel+=4; }; //ersten stein berechnen: klappt nicht,wenn man die kommentarstriche wegmacht //do //{ x=rand()%(xbereich-1); y=rand()%(ybereich-1); //} //while(feld[x][y]!=leer); if(feld[x][y]!=leer) { x=rand()%(xbereich-1); y=rand()%(ybereich-1); }; feld[x][y]=stein; InvalidateRect(hwnd,NULL,TRUE);//alles neu zeichnen SetTimer(hwnd,SnakeTimer,SnakeSpeed,NULL);//tiemr für die schlange setzen }; void FeldLine(unsigned char x1,unsigned char y1,unsigned char x2,unsigned char y2)//wand ins feld zeinen { //Routine arbeitet nur mit Integer-Werten - also schnell! unsigned char x,y; signed char xinc,yinc; short d,c,m,hx,hy; x = x1; y = y1; d = 0; hx = x2 - x1; //Anzahl der Punkte auf der X-Achse hy = y2 - y1; xinc = 1; yinc = 1; if(hx < 0) { xinc = -1; hx *=-1; }; if(hy<0) { yinc = -1; hy*=-1; }; if(hy <= hx) { c = 2 * hx; m = 2 * hy; while(x!=x2) { feld[x][y]=wand; x+=xinc; d+=m; if(d>hx) { y+=yinc; d-=c; }; }; } else { c = 2 * hy; m = 2 * hx; while(y!=y2) { feld[x][y]=wand; y+=yinc; d+=m; if(d>hy) { x+=xinc; d-=c; }; }; }; feld[x][y]=wand; };resource.h:
#define IDM_NEU 200 #define IDM_BEENDEN 201 #define IDM_SLOW 202 #define IDM_NORMAL 203 #define IDM_FAST 204 #define IDM_VERYFAST 205 #define IDM_VERYSLOW 206 #define IDM_INFO 207 #define IDM_EXTFAST 208 #define IDM_RESET 209 #define IDM_KILLY 210 #define IDM_KILLN 211resource.rc:
#include "resource.h" UNSERMENU MENU BEGIN POPUP "&Spiel" BEGIN MENUITEM "&Neues Speiel (F2)", IDM_NEU MENUITEM "&Level neu starten (F3)", IDM_RESET MENUITEM SEPARATOR MENUITEM "B&eenden (ALT+F4)", IDM_BEENDEN END POPUP "&Speed" BEGIN MENUITEM "&Very slow (1)", IDM_VERYSLOW MENUITEM "&Slow (2)", IDM_SLOW MENUITEM "&Normal (3)", IDM_NORMAL MENUITEM "&Fast (4)", IDM_FAST MENUITEM "&Very fast (5)", IDM_VERYFAST MENUITEM "&Extremly fast (6)", IDM_EXTFAST END POPUP "&Mode" BEGIN MENUITEM "&Cut on crash (ALT+C)", IDM_KILLN MENUITEM "&Kill on crash (ALT+K)", IDM_KILLY END POPUP "&Hülfe" BEGIN MENUITEM "&Info (F1)", IDM_INFO END END SHORTCUTS ACCELERATORS BEGIN "Q", IDM_BEENDEN, VIRTKEY, ALT "C", IDM_KILLN, VIRTKEY, ALT "K", IDM_KILLY, VIRTKEY, ALT ENDJa, DEV-C++ hat einen, aber ich weiss leider nicht wie man den benutzt.
MfG Mark