PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C++ Labyrinth Spiel


nobody
05.03.2004, 09:12
Habe ein weiteres Problem. In diesem Programm soll eine Linie durch ein Labyrinth laufen, bis es das Ziel erreicht. Nur leider stürzt das Programm an bestimmten Stellen ab, es funzt nur teilweise. Probiert es bitte mal aus. THX


/******************************************************************
Programm: Roboter.cpp
Funktion: Simulationprogramm für die Routenfindung
Bemerkung:
Funktion sucheWeg()
Die Funktion sucht den Weg durch das Labyrinth.
Hindernisse haben die Farbe rot. Das Ziel ist grün
und der zurückgelegte Weg wird schwarz markiert.
Die Werkshalle ist nach Himmelrichtungen aufgeteilt.

Autor(en): Matthias Brune & FE56
letzte Aenderung:
04-01-17 MB erste Version
******************************************************************/
#include "stdafx.h"

HWND hWnd = 0;

//=================================================================
// Globale Parameter zur Steuerung, nicht veraendern!
//=================================================================
int itemsPerLine=3; // Anzahl der Bloecke pro Zeile [1-20]
int randomOn=0; // Zufaelligkeit des Labyrinths [0;1]


//=================================================================
// Prototypen
//=================================================================

void sucheWeg(HDC hDC, int startx, int starty, int zielx, int ziely);

void sleep (int usec);
void generiereLabyrinth(HDC hDC);
void zeichneRechteck(HDC hDC,int x, int y, unsigned long chDC);
void zeichneBegrenzung(HDC hDC,int x, int y, unsigned long chDC);
int zufall(void);

//=================================================================
// Hauptprogramm
//=================================================================

int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
hWnd = CreateMainWindow(hInstance);
if(0 == hWnd)
{
MessageBox(0,"Fehler","Fehler",MB_OK);
return 0;
}
MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}

HWND CreateMainWindow(HINSTANCE hInstance)
{
WNDCLASSEX wndClass;
wndClass.cbSize = sizeof(WNDCLASSEX);
wndClass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = WindowFunc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = hInstance;
wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.lpszMenuName = NULL;
wndClass.lpszClassName = "WindowClass";
wndClass.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wndClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
RegisterClassEx(&wndClass);
return CreateWindowEx(NULL, "WindowClass", "Simulation - Lagerhalle", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 300, 300, NULL, NULL, hInstance, NULL);
}
LRESULT CALLBACK WindowFunc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
break;

case WM_PAINT:
PAINTSTRUCT ps;
HDC hDC;
int startx, starty, zielx, ziely;

hDC = BeginPaint(hWnd,&ps);

startx = 10;
starty = 10;
zielx = 250;
ziely = 250;
generiereLabyrinth(hDC);
//sleep(10000);
// Start

sucheWeg(hDC, startx, starty, zielx, ziely);

// Ende

EndPaint(hWnd,&ps);

return 0;
break;
}

return (DefWindowProc(hwnd, msg, wParam, lParam));
}



// ==========================================================================
// Funktion zur Wegbestimmung -- sehr wichtig!
// ==========================================================================

/******************************************************************
Funktion: sucheWeg()
Die Funktion sucht den Weg durch das Labyrinth der Werkshalle
Hindernisse haben die Farbe rot. Das Ziel ist grün und der
zurückgelegte Weg wird schwarz markiert. Die Werkshalle ist
nach Himmelrichtungen aufgeteilt.

Hier scheint es ein Problem zu geben, da der Roboter nicht
am Ziel ankommt.

Autor(en): Matthias Brune & FE56
letzte Aenderung:
04-02-05 MB erste Version
******************************************************************/
void sucheWeg(HDC hDC, int startx, int starty, int zielx, int ziely)
{
int x,y,
angekommen,
positionX,
positionY;
COLORREF rot = RGB(255, 0, 0);
COLORREF blau = RGB( 0, 0,255);
COLORREF gruen = RGB( 0,255, 0);
COLORREF schwarz = RGB( 0, 0, 0);
COLORREF weiss = RGB(255,255,255);

// Richtungsbestimmung ueber die Variablen x und y
// x= 1; y=-1 => Nord (nach oben)
// x= 1; y=0 => Ost (nach rechts)
// x= 0; y=1 => Sued (nach unten)
// x=-1; y=0 => West (nach links)

angekommen=0;
positionX=startx;
positionY=starty;

x=1; y=0; // Erste Schritte nach Osten
while (angekommen != 1)
{
while ( (
GetPixel(hDC, positionX+x,positionY+y) != rot || // Kein Hindernis im Weg
GetPixel(hDC, positionX+x,positionY+y) == gruen // fahre in das Ziel
) && angekommen != 1 // wir sind noch nicht angekommen?
)
{
// Richtung ist moeglich, jetzt machen wir einen Schritt
positionX = positionX+x;
positionY = positionY+y;
if (GetPixel(hDC, positionX,positionY) == gruen)
{ // und überprüfen, ob wir schon am Ziel sind (grünes Feld)
// Ausstiegbedingung
angekommen=1;
}
SetPixel(hDC, positionX, positionY, schwarz);
// wir schlafen ein wenig, damit man den Weg des Roboters auch
// am Bildschirm nachvollziehen kann
sleep(10);
}

// Festlegen der Marschrichtung, nachdem wir auf ein Hindernis getroffen sind
if (GetPixel(hDC, positionX+1,positionY+0) == weiss)
{
x=1; y=0; // Nach Osten fahren
}
else
{
x=0; y=1; // Nach Sueden fahren
}

}
}















// unwichtige Hilfsfunktionen, nicht für die Problemloesung und die
// eigentliche Stunde interessant
// ==========================================================================
// Funktionen zur Generierung des Labyrinths per Zufallsgenerator
// ==========================================================================

void generiereLabyrinth(HDC hDC)
{

int i,j,x;
int startx, starty, zielx, ziely;

startx = 1;
starty = 10;
zielx = 250;
ziely = 250;

if (!itemsPerLine)
{
itemsPerLine = ((int) time((time_t*)NULL))%20;
}

for (i=0;i<=300-50;i=i+10)
{
for (j=0;j<itemsPerLine;j++)
{
x = zufall()%(300-50);
if ((x % 10) != 0) x=x+(10-(x%10));
zeichneRechteck(hDC, x, i, RGB(255,0,0));
}
}

zeichneRechteck(hDC, startx, starty, RGB(0,0,0));
zeichneRechteck(hDC, zielx, ziely, RGB(0,255,0));
zeichneBegrenzung(hDC,300-40, 300-40, RGB(255,0,0));
}

// ==========================================================================

void zeichneRechteck(HDC hDC,int x, int y, unsigned long chDC)
{
int i,j;

for (j=y; j<y+10; j++)
{
for (i=x; i<x+10; i++)
{
SetPixel(hDC, i, j, chDC);
}
}
}

// ==========================================================================

void zeichneBegrenzung(HDC hDC,int x, int y, unsigned long chDC)
{
int i;

for (i=0; i<=x; i++)
{
SetPixel(hDC, i, 0, chDC);
SetPixel(hDC, i, 1, chDC);
}

for (i=0; i<=x; i++)
{
SetPixel(hDC, i, y, chDC);
SetPixel(hDC, i, y+1, chDC);
}
for (i=0; i<=y; i++)
{
SetPixel(hDC, 0, i, chDC);
SetPixel(hDC, 1, i, chDC);
}

for (i=0; i<=y; i++)
{
SetPixel(hDC, x, i, chDC);
SetPixel(hDC, x+1, i, chDC);
}
}

// ==========================================================================

int zufall(void)
{
static int rerun = 0;

if (!rerun)
{
if (!randomOn)
{
srand( (unsigned) 1);
}
else
{
srand( (unsigned)time( NULL ) );
}
rerun = 1;
}
return rand();
}

// ==========================================================================

void sleep(int usec)
{
_sleep(usec);
}

MaSTaH
05.03.2004, 10:22
Also ohne Codetags kann man das nur sehr schwer lesen. Bist du mal mit dem Debugger durchgegangen?

Einiges was mir so aufgefallen ist:

1) Wenn du schon die WinAPI benutzt, dann nimm auch ihr Sleep() anstatt _sleep().
2) Warum zeichnest du die Rechtecke mit SetPixel? Die Windows GDI stellt extra die Funktion Rectangle bereit. Linien kannst du auch per API-Befehl zeichnen.
3) Die Funktion zufall() ist nicht wirklich gut durchdacht.

Um den Fehler eingrenzen zu können sollte ich auch etwas über die Art des Absturzes erfahren. Möglichkeiten:
a) Programm hängt sich auf (meist Endlosschleife)
b) Access-violation. Du schreibst oder liest in Speicher der dir nicht gehört.
c) irgendwas anderes.

buba
05.03.2004, 12:52
Also ohne Codetags kann man das nur sehr schwer lesen.
Sollte jetzt leichter fallen.

MaSTaH
05.03.2004, 13:38
Danke.

@Fabian: Also beim besten Willen... Stelle bitte eine Version online die auch kompilierbar ist. Das ist echt eine Zumutung. In dem Code werden Variablen verwendet, die nirgendwo deklariert sind, es fehlen Prototypen, Includes und sonst sind auch noch mehrere Syntaxfehler drin. Ich glaube nicht, dass das Ding jemals so kompiliert wurde. :rolleyes:

nobody
09.03.2004, 16:16
das ist auch ne schulaufgabe, die fehler müssen ja eliminiert werden