Snake mit C - Kleines Problem

Diskutiere Snake mit C - Kleines Problem im Developer Network Forum im Bereich Hardware & Software Forum; Hey :D Ich habe da son Problem. Und zwar müssen wir Snake mit C programmieren. Ich hatte auch schon nen Plan aber bin jz draufgekommen, dass...
  • Snake mit C - Kleines Problem Beitrag #1
N

nagiii

Aktives Mitglied
Dabei seit
22.11.2009
Beiträge
37
Reaktionspunkte
0
Ort
Österreich/Niederösterreich
Hey :D

Ich habe da son Problem. Und zwar müssen wir Snake mit C programmieren.
Ich hatte auch schon nen Plan aber bin jz draufgekommen, dass der nicht ged und habe auch nicht mehr viel Zeit hoffe jmd kann mir helfen...
es sollte mit arrays sein und kein goto verwenden aber ich habs mit den 2-dimensionalen arrays nicht so.

thx für die hilfe schonmal

mfg. nagiii
 
  • Snake mit C - Kleines Problem Beitrag #2
T

TrµMAn

Bekanntes Mitglied
Dabei seit
23.10.2006
Beiträge
4.882
Reaktionspunkte
2
Ort
Wuppertal
okay mal kurz wie man das machen KANN

2 2-Dimensionale Arrays -> eins fürs Feld und eins für die Schlange
beim Feld brauchst du eben int feld[breite][höhe]
Hier musst du dir dann eine Funktion schreiben, die das Feld mit erkennbaren Werten füllt, so dass du darauf beim Zeichnen prüfen kannst (bsp: 0 = leeres feld -> Ausgabe " ", 1 = schlange -> Ausgabe "o", 2 = Frucht -> Ausgabe "x")
bei der Schlange brauchst du nur int schlange[MAX_SCHLANGE_LAENGE][2]
und eine Variable für die aktuelle Länge
Die Schlange brauchst du in der Form, da du jeweils die X und die Y koordinate speichern musst
Dafür brauchst du dann auch jeweils noch eine Variable, damit du weißt, wo sich dein Kopf grad befindet.

hoffe dir erstmal einen weiteren Denkansatz gegeben zu haben

btw, ich hab das ganze im Internet gefunden ... zusammen mit einem scheinbar kompletten und funktionierenden Code ... ich möchte dir trotzdem ans Herz legen, das selbst zu schreiben!
 
  • Snake mit C - Kleines Problem Beitrag #3
N

nagiii

Aktives Mitglied
Dabei seit
22.11.2009
Beiträge
37
Reaktionspunkte
0
Ort
Österreich/Niederösterreich
also warum muss bei der Schlange 2 hinten stehn?

und wie kann ich bei 2 2d-arrays wissen, wo sich die schlange im feld befindet und mit 1 kennzeichnen?

aber danke hat schon ziemlich geholfen
 
  • Snake mit C - Kleines Problem Beitrag #4
N

nagiii

Aktives Mitglied
Dabei seit
22.11.2009
Beiträge
37
Reaktionspunkte
0
Ort
Österreich/Niederösterreich
Mein Code sieht bis jetzt so aus...also das "Futter" fehlt noch und fel und schlange...
alles was errors gab hab ich ma wegkommentiert so rennts bis jetzt:

Code:
#include<stdio.h>
#include<conio.h>
#include<windows.h>

#define RECHTS 77
#define UNTEN 80
#define LINKS 75
#define OBEN 72
#define LEICHT 49
#define MITTEL 50
#define SCHWER 51

int pfeil();
void menu(int *alive);
void neu(/*int feld[80][25], int snake[90][2],*/ int *action, int *alive, int *grad, int *score);
void move(/*int snake[90][2],*/ int action, int grad, int *score, int *alive);

int main() {
  int feld[80][24];
  int snake[90][2];
  int action;
  int alive;
  int grad;
  int score;
  menu(&alive);
  while(alive) {
    if(alive == 2) neu(/*feld[80][25], snake[90][2],*/ &action, &alive, &grad, &score);
    move(/*snake[90][2],*/ action, grad, &score, &alive);
    system("cls");
    if(kbhit()) {
      switch(pfeil()) {
        case 100:
        case -77: action = RECHTS;
                  break;
        case 115:
        case -80: action = UNTEN;
                  break;
        case  97:
        case -75: action = LINKS;
                  break;
        case 119:
        case -72: action = OBEN;
                  break;
        case 27:
        case 112: menu(&alive);
      }
    }
  }
  return 0;
}

int pfeil() {
  int taste = getch();
  if(taste == 224) {
    taste = getch();
    return -taste;
  }
  return taste;
}

void menu(int *alive) {
  char action;
  int exit = 0;
  if(*alive == 1) {
    printf("\n \\--------------------------/\n"
           " |      .:Pausemenue:.      |\n"
           " |  p:    Spiel fortsetzen  |\n");
  } else if(*alive == 3) {
    printf("\n \\--------------------------/\n"
           " |      .:GAME OVER!:.      |\n");
  } else {
    printf("\n \\--------------------------/\n"
           " |      .:Hauptmenue:.      |\n");
  }
  printf(" |  n: Neues Spiel starten  |\n"
         " |  b:             Beenden  |\n"
         " /--------------------------\\\n");
  do{
    exit = 0;
    action = getch();
    switch(action) {
      case 'p': if(*alive != 1) exit = 1;
                break;
      case 'n': *alive = 2;
                break;
      case 'b': *alive = 0;
                break;
      default: exit = 1;
    }
  } while(exit);
  system("cls");
}

void move(/*int snake[90][2], */int action, int grad, int *score, int *alive) {
  Sleep(1/grad*100);
}

void neu(/*int feld[80][25], int snake[90][2],*/ int *action, int *alive, int *grad, int *score) {
  int exit = 0;
  *alive = 1;
  *score = 0;
  *action = RECHTS;
  printf("\n \\--------------------------/\n"
         " |  .:Schwierigkeitsgrad:.  |\n"
         " |  1:              Leicht  |\n"
         " |  2:              Mittel  |\n"
         " |  3:              Schwer  |\n"
         " /--------------------------\\\n");
  do{
    *grad = getch();
    switch(*grad) {
        case '1': case '2': case '3': break;
        default: exit = 1;
    }
  }while(exit);
}

was müsste man ändern und hinzufügen, damit alles gehen würde??

achja, und bei Leicht und Mittel soll man durch Wände durch können und gegebüber wieder reinkommen und bei Schwer soll das Game dann Over sein wenn man gegen Wand kracht.

mfg.
 
Zuletzt bearbeitet:
  • Snake mit C - Kleines Problem Beitrag #5
cmddegi

cmddegi

Bekanntes Mitglied
Dabei seit
12.07.2001
Beiträge
4.740
Reaktionspunkte
0
Ort
Austria
Habt ihr keine vorgegebenen Funktionen für z.B. das Zeichnen des Spielfelds? In jedem Frame alles mit cls zu löschen und das ganze Spielfeld neu zu zeichnen erscheint mir jetzt nicht direkt effizient oder elegant; das wird wahrscheinlich sehr flimmern und/oder viel zu langsam sein. Windows hat zwar Funktionen um direkt in der Konsole in Farbe an beliebigen Positionen zu schreiben, aber für den Anfang erscheint mir das etwas zu komplex.

Ansonsten kannst du dich mal im Netz nach dem Code von Nibbles umsehen; das damals bei DOS als Beispielprogramm für QBasic dabei war. Da wird die ganze Spielmechanik recht schnell deutlich; und QBasic dürfte kein Problem zu verstehen sein, wenn man C kann.

/edit: Damit du es etwas leichter hast:
http://shiar.nl/projects/dos/nibbles.bas
 
Zuletzt bearbeitet:
  • Snake mit C - Kleines Problem Beitrag #6
T

TrµMAn

Bekanntes Mitglied
Dabei seit
23.10.2006
Beiträge
4.882
Reaktionspunkte
2
Ort
Wuppertal
Mein Code sieht bis jetzt so aus...also das "Futter" fehlt noch und fel und schlange...
alles was errors gab hab ich ma wegkommentiert so rennts bis jetzt:

Code:
#include<stdio.h>
#include<conio.h>
#include<windows.h>

#define RECHTS 77
#define UNTEN 80
#define LINKS 75
#define OBEN 72
#define LEICHT 49
#define MITTEL 50
#define SCHWER 51

int pfeil();
void menu(int *alive);
void neu(/*int feld[80][25], int snake[90][2],*/ int *action, int *alive, int *grad, int *score);
void move(/*int snake[90][2],*/ int action, int grad, int *score, int *alive);

int main() {
  int feld[80][24];
  int snake[90][2];
  int action;
  int alive;
  int grad;
  int score;
  menu(&alive);
  while(alive) {
    if(alive == 2) neu(/*feld[80][25], snake[90][2],*/ &action, &alive, &grad, &score);
    move(/*snake[90][2],*/ action, grad, &score, &alive);
    system("cls");
    if(kbhit()) {
      switch(pfeil()) {
        case 100:
        case -77: action = RECHTS;
                  break;
        case 115:
        case -80: action = UNTEN;
                  break;
        case  97:
        case -75: action = LINKS;
                  break;
        case 119:
        case -72: action = OBEN;
                  break;
        case 27:
        case 112: menu(&alive);
      }
    }
  }
  return 0;
}

int pfeil() {
  int taste = getch();
  if(taste == 224) {
    taste = getch();
    return -taste;
  }
  return taste;
}

void menu(int *alive) {
  char action;
  int exit = 0;
  if(*alive == 1) {
    printf("\n \\--------------------------/\n"
           " |      .:Pausemenue:.      |\n"
           " |  p:    Spiel fortsetzen  |\n");
  } else if(*alive == 3) {
    printf("\n \\--------------------------/\n"
           " |      .:GAME OVER!:.      |\n");
  } else {
    printf("\n \\--------------------------/\n"
           " |      .:Hauptmenue:.      |\n");
  }
  printf(" |  n: Neues Spiel starten  |\n"
         " |  b:             Beenden  |\n"
         " /--------------------------\\\n");
  do{
    exit = 0;
    action = getch();
    switch(action) {
      case 'p': if(*alive != 1) exit = 1;
                break;
      case 'n': *alive = 2;
                break;
      case 'b': *alive = 0;
                break;
      default: exit = 1;
    }
  } while(exit);
  system("cls");
}

void move(/*int snake[90][2], */int action, int grad, int *score, int *alive) {
  Sleep(1/grad*100);
}

void neu(/*int feld[80][25], int snake[90][2],*/ int *action, int *alive, int *grad, int *score) {
  int exit = 0;
  *alive = 1;
  *score = 0;
  *action = RECHTS;
  printf("\n \\--------------------------/\n"
         " |  .:Schwierigkeitsgrad:.  |\n"
         " |  1:              Leicht  |\n"
         " |  2:              Mittel  |\n"
         " |  3:              Schwer  |\n"
         " /--------------------------\\\n");
  do{
    *grad = getch();
    switch(*grad) {
        case '1': case '2': case '3': break;
        default: exit = 1;
    }
  }while(exit);
}

was müsste man ändern und hinzufügen, damit alles gehen würde??

achja, und bei Leicht und Mittel soll man durch Wände durch können und gegebüber wieder reinkommen und bei Schwer soll das Game dann Over sein wenn man gegen Wand kracht.

mfg.

Ohne direkt auf den Code einzugehen, würde ich dir zumindest vorschlagen, die sache anders anzugehen!

Versuch doch erstmal, die einfachste variante des Spiels auf die Beine zu stellen, bevor du mit mehreren Schwierigkeitsgraden anfängst oder dir darüber den Kopf zerbrichst, was da mal möglich sein soll.

so zu den anderen sachen:
Warum ich int schlange[MAX_SCHLANGE_LAENGE][2] genommen habe, also die 2 im zweiten Index, liegt an meiner Persönlichen Vorliebe und meiner Vorstellung eines Arrays als Tabelle.
Für mich ist der erste Index nunmal die Zeile und der zweite die Spalte, wenn ich die Zeilen durchgehe (erster Index) kann ich in den beiden Spalten (zweiter Index) nach der X und nach der Y Position suchen.

Wie du die Schlange ins Feld bekommst:
z.B. mit dieser Funktion (Variablen für Feld, Schlange und aktuelle_laenge sind Global definiert, was ich dir hier auch raten würde, da du sonst sehr häufig viele Parameter übergeben musst und für dieses kleine Programm sollte das vertretbar sein)
Code:
void ZeichneSchlange()
{
    for ( int i = 0; i <= aktuelle_laenge; i++ )
    {
        int iX = Schlange[i][0];
        int iY = Schlange[i][1];
        Feld[iY][iX] = 1;
    }
}
 
  • Snake mit C - Kleines Problem Beitrag #7
Anno1989

Anno1989

Bekanntes Mitglied
Dabei seit
30.04.2006
Beiträge
1.293
Reaktionspunkte
0
Ort
NRW
Hi, habe vor ein paar Monaten ein Snake für die Console programmiert.
Es funktioniert mit scrcls() eigentlich ganz gut und der Spaß bleibt auch nicht auf der Strecke.
Ich arbeite ebenfalls mit einem Array für das Feld, wobei ich Schlangenkopf, Schlangenkörper, Nahrung und Grenze unterscheide. Die Schlange an sich besteht aus einer vom In - und Output (getAsyncKeyState()) getrennten Klasse, die sich selber zum folgenden Schlangenglied verkettet.
Im Renderloop wird dann bei jedem Positionswechsel das folgende Glied an die eigene Position gesetzt. So gibt es auch keine Probleme beim hinzufügen neuer Glieder.

Mein Input sieht wie folgt aus, falls der hilft, da ich anfangs auch überlegt habe, wie ich den am besten hinbekomme:
Code:
for(unsigned i = 37; i < 41; i++) {
		if(GetAsyncKeyState(i)) {
			switch(i)
			{
			case 37:			//Links
				SSnake().setMovingDirection(SD_LEFT);
				break;
			case 38:			//Oben
				SSnake().setMovingDirection(SD_UP);
				break;
			case 39:			//Rechts
				SSnake().setMovingDirection(SD_RIGHT);
				break;
			case 40:			//Unten
				SSnake().setMovingDirection(SD_DOWN);
				break;
			}
		}
	}
Snake ist eine Singleton Klasse deswegen mein S davor um drauf zuzugreifen, nicht wundern.
Wie gesagt es läuft ganz gut, die Klasse Snake hat dann eine tick() Funktion, die alle Glieder dann verschiebt.
So sieht mein Mainloop aus:
Code:
while(SSnake().isRunning()) {
			//Input verarbeiten
			processInput();
			//Snake verschieben
			SSnake().tick();
			//Bildschrim löschen
			system("cls");
			//Malen
			drawField();
		}

Vielleicht hilft es dir. So klappt es auf jeden Fall. ;)

MfG
Anno1989
 
  • Snake mit C - Kleines Problem Beitrag #8
N

nagiii

Aktives Mitglied
Dabei seit
22.11.2009
Beiträge
37
Reaktionspunkte
0
Ort
Österreich/Niederösterreich
So ich habe es jetzt mal programmiert soweit ich weiß hat es keine Bugs, es legt 1 Datei für den Highscore an und multiplayer ist möglich...falls Bugs auftreten pls PM an mich...

auf manchen PCs hängt das Spiel sehr(self-tested) kA warum wäre über eine Begründung erfreut :D

http://ul.to/4xqtu8
--> ja ich weiß es ist ne .exe aber man kann mir 100%ig vertrauen is kein Virus und wird auch nicht als solcher erkannt.
 
Zuletzt bearbeitet:
  • Snake mit C - Kleines Problem Beitrag #9
N

nagiii

Aktives Mitglied
Dabei seit
22.11.2009
Beiträge
37
Reaktionspunkte
0
Ort
Österreich/Niederösterreich
ich kann meinen Beitrag jetzt leider nicht mehr editieren aber hab eben noch eine kleinigkeit geändert neuer DL-Link:
http://ul.to/7qzhgy

mfg. nagiii
 
  • Snake mit C - Kleines Problem Beitrag #10
U

UnimatrixZero

Bekanntes Mitglied
Dabei seit
27.06.2001
Beiträge
645
Reaktionspunkte
0
Sieht gut aus.

Noch ein Tipp: Durch das Löschen und Neuzeichnen flackert die Grafik recht stark. Versuch mal, nur die sich ändernden Zeichen neu auszugeben. Du könntest Dir z.B. 2 Arrays anlegen, in die Du abwechselnd den Bildschirm abspeicherst. D.h. ein Array enthält immer das, was gerade zu sehen ist. Durch Vergleich beider Arrays findest Du raus, was sich geändert hat. Nur diese Zeichen musst Du neu setzen. Das sollte nicht nur das Flackern beseitigen, sondern auch die Ausgabe beschleunigen.
 
Thema:

Snake mit C - Kleines Problem

ANGEBOTE & SPONSOREN

https://www.mofapower.de/

Statistik des Forums

Themen
213.180
Beiträge
1.579.174
Mitglieder
55.879
Neuestes Mitglied
stonetreck
Oben