Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

idontknow

unregistriert

1

06.04.2009, 11:45

[C++] Konsolen Programm (ein Feld!) buggt total!

hey leute!

Ich erstelle zur Zeit in der Schule aus SPass, ein Konsolenprogramm!

Das Programm, erstellt ein Feld aus Zeichen ('|').
mit den Tasten 'wasd' kann man sich in dem Feld herumbewegen, gestuert wird das ganze durch eine INT variable die die Position angibt, angezeigt durch einen Buchstaben: 'O'

Aber das Programm buggt, total, es werden ständig mehrere O's angezeiogt, und ads Bewegen des eigentlichen Os gerät total auser Kontrolle weil es teils verschwindet teils Sprünge macht ect. Total buggy eben -.-

Ich häng mal den Source Code an,. wäre nett wenns wer Compilieren/Testen könnte!

Eine Anmerkung noch:
Der Code ist teils mit Debug Funktionnen versehen, die ich noch nciht removt habe (Tests eben...) und auch mit Headern die nicht genutzt werden (tests eben.. für bestimmte Funktionen zum testen!)

Und noch etwas, kennt jmd. eine alternativ Funktion für system("cls")? Ich benutze die nur weil ich nix anderes habe.... -.-

mfg

Source Code:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <windows.h>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>

#define ROWS 15
#define COLUMNS 25

#define SIGN '|'
#define SELECTED 'O'


char cSelect = ' ';
char cSigns[ROWS*COLUMNS];
int iField;






int main()
{
    
    for(int i = 0; i < ROWS; i++)
    {
      for(int i2 = 0; i2 < COLUMNS; i2++)
      {
         cSigns[i * i2] = SIGN;    
      }
    }
    
    iField = 1;
    cSigns[1] = SELECTED;
//    cSelect = cSigns[ROWS * COLUMNS];

    
    
    while(1)
    {     
       // zeichnen...

       std::cin.clear();
       //std::cin.ignore(std::numeric_limits<int>::max(),'\n');

       for(int i = 1; i < ROWS; i++)
       {
          for(int i2 = 1; i2 < COLUMNS; i2++)
          {
             if(iField != i * i2)
                std::cout << cSigns[i * i2];
             else
                std::cout << SELECTED;
          }  
          std::cout << std::endl;   
       } 
       //Debug, Feld position!

       std::cout << iField;
       // Clear screen:

       system("cls");
       
       // Exit.... by pressing 0;

       if(GetAsyncKeyState(48))
          break;                   
       
       if(GetAsyncKeyState(65)) // a

       {
          iField = iField - 1;
       }
       
       if(GetAsyncKeyState(68)) // d

       {
          iField = iField + 1;
       }
       
       if(GetAsyncKeyState(83)) // s

       {
          iField = iField + COLUMNS;
       }
       
       if(GetAsyncKeyState(87)) // w

       {
          iField = iField - COLUMNS;
       }
       // Crash' vermeiden!

       if(iField < 1)
         iField = 1;
       if(iField > ROWS * COLUMNS)
         iField = ROWS * COLUMNS;
       
       
    }
    return 0;
};


mfg und Danke!

n0_0ne

1x Contest-Sieger

  • Private Nachricht senden

2

06.04.2009, 12:04

Beim Array fängst du mit 0 an zu zählen, später beim aktualisieren aber bei 1 (in beiden fors) ich denke deshalb greifst du auf falsche array einträge zu...

idontknow

unregistriert

3

06.04.2009, 12:07

der index wird ja aus 2 wertern per multiplikation errechnet!

wenn ich bei 0 anfangen würde zu zählen, dann wäre der index der kompletten ersten reihe 0 und es sollte ja für jeden Index einen seperaten Index geben ;) deshalb habe ich da angefangen zu zählen...

Ich kann aber nciht verstehen wieso es daran liegen soll!

n0_0ne

1x Contest-Sieger

  • Private Nachricht senden

4

06.04.2009, 12:14

also den index aus i * i2 zu berechnen ist denke ich sowieso blödsinn ^^
müsste i * ROWS + i2 sein
jedenfalls im falle deines 1-dimensionalen array... ansonsten wäre es array[i1][i2]

Edit: sry i * COLUMS+ i2 ^^

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <windows.h>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>

#define ROWS 15
#define COLUMNS 25

#define SIGN '|'
#define SELECTED 'O'

char cSigns[ROWS*COLUMNS];
int iField;

int main()
{
    for(int i = 0; i < ROWS; i++)
    {
      for(int i2 = 0; i2 < COLUMNS; i2++)
      {
         cSigns[i * COLUMNS + i2] = SIGN;
      }
    }

    iField = 0;

    while(1)
    {
       // zeichnen...

       std::cin.clear();
       for(int i = 0; i < ROWS; i++)
       {
          for(int i2 = 0; i2 < COLUMNS; i2++)
          {
             if(iField != i * COLUMNS + i2)
                std::cout << cSigns[i * COLUMNS + i2];
             else
                std::cout << SELECTED;
          }
          std::cout << std::endl;
       }
       //Debug, Feld position!

       std::cout << iField;
       // Clear screen:

       system("cls");

       // Exit.... by pressing 0;

       if(GetAsyncKeyState(48))
          break;

       if(GetAsyncKeyState(65)) // a

       {
          iField = iField - 1;
       }

       if(GetAsyncKeyState(68)) // d

       {
          iField = iField + 1;
       }

       if(GetAsyncKeyState(83)) // s

       {
          iField = iField + COLUMNS;
       }

       if(GetAsyncKeyState(87)) // w

       {
          iField = iField - COLUMNS;
       }
       // Crash' vermeiden!

       if(iField < 0)
         iField = 0;
       if(iField > (ROWS * COLUMNS) -1)
         iField = ROWS * COLUMNS -1;
    }
    return 0;
};

idontknow

unregistriert

5

06.04.2009, 14:29

JUHUUUUU!!

Danke es funktioniert!

Könntest du mir mal sagen, woran der Fehler jetzt genau lag?

n0_0ne

1x Contest-Sieger

  • Private Nachricht senden

6

06.04.2009, 14:30

Vergleich doch einfach den Code ^^ hauptsächlich an den sachen, die ich oben schon geschrieben habe

idontknow

unregistriert

7

06.04.2009, 14:34

Jop ok danke!

Eine weitere Frage: Ich will jetzt adden, das wenn man am Rand hinauslaufen würde (also links, rechts, oben, unten) das dann, das bewegungsobjekt stehen bleibt!

momentan verusche ichs durch eine for schleiufe die einzelnen Grenz werte zu überprüfen und iField dementsprechend zu setzen, gibts da eine performantere und bessere Idee (z.B. mit Modulo oder so?)

nen Beispiel, wie ichs haben will:

Das Objekt wird ans Ende von Reihe 1 bewegt.
Dann nochmal um eins, momentan wirds dann ann den Anfang von Reihe 2 bewegt, aber es soll einfach stehen bleiben!

mfg

n0_0ne

1x Contest-Sieger

  • Private Nachricht senden

8

06.04.2009, 14:51

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <windows.h>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>

#define ROWS 15
#define COLUMNS 25

#define SIGN '|'
#define SELECTED 'O'

char cSigns[ROWS*COLUMNS];
int iField;

int main()
{
    for(int i = 0; i < ROWS; i++)
    {
      for(int i2 = 0; i2 < COLUMNS; i2++)
      {
         cSigns[i * COLUMNS + i2] = SIGN;
      }
    }

    iField = 0;
    while(1)
    {
       // zeichnen...

       std::cin.clear();
       for(int i = 0; i < ROWS; i++)
       {
          for(int i2 = 0; i2 < COLUMNS; i2++)
          {
             if(iField != i * COLUMNS + i2)
                std::cout << cSigns[i * COLUMNS + i2];
             else
                std::cout << SELECTED;
          }
          std::cout << std::endl;
       }
       //Debug, Feld position!

       std::cout << iField;
       // Clear screen:

       system("cls");

       // Exit.... by pressing 0;

       if(GetAsyncKeyState(48))
          break;

       if(GetAsyncKeyState(65)) // a

       {
           if(iField % COLUMNS != 0)
          iField = iField - 1;
       }

       if(GetAsyncKeyState(68)) // d

       {
          if(iField % COLUMNS != COLUMNS -1)
              iField = iField + 1;
       }

       if(GetAsyncKeyState(83)) // s

       {
          iField = iField + COLUMNS;
       }

       if(GetAsyncKeyState(87)) // w

       {
          iField = iField - COLUMNS;
       }
       // Crash' vermeiden!

       if(iField < 0)
         iField += COLUMNS;
       if(iField > (ROWS * COLUMNS) -1)
         iField -= COLUMNS;
    }
    return 0;
};

so gehts effizienter, also einfach nur unten die ifs leicht modifiziert... links+rechts mit modulo, oben+unten dann einfach wieder zurückgerechnet (in der crash abfrage) (kannst aber auch mit div in den if abfragen für die tasten machen...).
BTW, ich würde dir empfehlen für sowas immer ein 2-dimensionales array zu nehmen, da lässt sich der code besser lesen, ist wohl schneller, weil man nicht mit div und mod rumalbern muss usw...

idontknow

unregistriert

9

06.04.2009, 14:58

so gehts gar nicht mehr -.-

Kann das daran liegen, dass iField am Anfang auf 0 gesetzt ist?

Wenn ich iField auf 1 setze, dann gehts vorübergehen, denn sobald ich an den linken Rand komme, kann ich mich davon nicht mehr wegbewegen, also nur hoch und runter!

Dabei reicht es wenn ich links an den Rand komme egal in welcher Reihe!


edit: ohh sry, hab da bei einem was flasches reinkopiert -.-
*<- idiot!*

edit2:

also Danke klappt!

hab nach dem Schema bei w noch:

C-/C++-Quelltext

1
2
3
4
if(iField - COLUMNS < 0)
             iField = iField;
          else
             iField = iField - COLUMNS;

geaddet und bei s

C-/C++-Quelltext

1
2
3
4
 if(iField + COLUMNS > ROWS * COLUMNS - 1)
              iField = iField;
          else
             iField = iField + COLUMNS;


Jetzt klappts wunderbar :D

Danke!

franz-21

Treue Seele

Beiträge: 101

Wohnort: Bayern

Beruf: Schüler

  • Private Nachricht senden

10

10.04.2009, 22:00

Ein bisschen spät aber hier etwas zu deiner Anfangsfrage

Zitat

eine alternativ Funktion für system("cls")?

Die Funktion:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
void clrscr()
{
COORD coordScreen = { 0, 0 }; /* here's where we'll home the
cursor */
BOOL bSuccess;
DWORD cCharsWritten;
CONSOLE_SCREEN_BUFFER_INFO csbi; /* to get buffer info */
DWORD dwConSize; /* number of character cells in the current
buffer */
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
/* get the number of character cells in the current buffer
*/
bSuccess = GetConsoleScreenBufferInfo(hConsole, &csbi);
dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
/* fill the entire screen with blanks */
bSuccess = FillConsoleOutputCharacter(hConsole, (TCHAR) ' ',
dwConSize, coordScreen, &cCharsWritten);
/* get the current text attribute */
bSuccess = GetConsoleScreenBufferInfo(hConsole, &csbi);
/* now set the buffer's attributes accordingly */
bSuccess = FillConsoleOutputAttribute(hConsole,
csbi.wAttributes,
dwConSize, coordScreen, &cCharsWritten);
/* put the cursor at (0, 0) */
bSuccess = SetConsoleCursorPosition(hConsole, coordScreen);
return;
}

Werbeanzeige