Eure Meinung (Snake C++)
-
Hallo an alle,
ich programmiere noch nicht so lange C++ und würde gern eure Meinungen und Verbesserungsvorschläge zum Aufbau, Programmierstill usw. hören.
Ich habe es mit MVC++ 2008 Express Edition geschrieben.
Der Code ist etwas umfangreich :#include <iostream> #include <conio.h> #include <string> #include <ctime> #include <windows.h> #include <deque> #include <string> #define UP 'w' #define DOWN 's' #define LEFT 'a' #define RIGHT 'd' #define ESC 27 using namespace std; struct Pos_t { int x,y; bool operator ==(Pos_t& pos) { return pos.x==x && pos.y==y; } }; class Spielfeld_t //Singleton { Pos_t Spielfeld; Spielfeld_t(int x,int y){ Spielfeld.x=x; Spielfeld.y=y; } static Spielfeld_t* instance; public: static Spielfeld_t* getInstance(); int getSizeX(); int getSizeY(); void draw(); }; class Futter_t { Pos_t pos; char Zeichen; public: Futter_t(){ Zeichen='X'; } void set(int x,int y); Pos_t getPos(); void draw(); }; class Snake_t { protected: deque<Pos_t> pos; private: int Laenge; char Koerper; char Kopf; public: void set(int x,int y,int laenge,char koerper,char kopf); void move(char r); void draw(); bool istKollision(Futter_t &f); bool istKollision(Snake_t &s); bool istAufWand(); void fressen(){Laenge++;} }; class Profil_t { string Name; int Punkte; public: Profil_t(std::string name); string getName(); int getPunkte(); void addPunkte(int n); void show(); }; class Highscore_t { std::deque<Profil_t*> Profile; public: void Add(Profil_t* profil); void show(); ~Highscore_t(){ std::deque<Profil_t*>::iterator i; for (i = Profile.begin(); i != Profile.end(); ++i) delete *i; } }; class Screen_t //Singleton { char Screen[200][200]; int xSize,ySize; Screen_t(){} static Screen_t* instance; public: static Screen_t* getInstance(); void clear(); void init(int x,int y); void set(int x,int y,char c); void show(); }; void gotoXY(int x, int y) { HANDLE hStdout; COORD coordScreen = { 0, 0 }; hStdout = GetStdHandle(STD_OUTPUT_HANDLE); coordScreen.X = x; coordScreen.Y = y; SetConsoleCursorPosition( hStdout, coordScreen ); } //------------------------Screen_t---------------------------------------- Screen_t* Screen_t::instance=0; Screen_t* Screen_t::getInstance() { if(!instance) instance=new Screen_t(); return instance; } void Screen_t::clear() { for(int x=0;x<=xSize;x++){ for(int y=0;y<=ySize;y++){ Screen[x][y]=' '; } } } void Screen_t::init(int x,int y) { xSize=x; ySize=y; } void Screen_t::set(int x,int y,char c) { Screen[x][y]=c; } void Screen_t::show() { gotoXY(0,0); for(int y=0;y<=ySize;y++){ for(int x=0;x<=xSize;x++){ cout<<Screen[x][y]; } cout<<endl; } } //------------------------Spielfeld_t---------------------------------------- const int SpielfeldX=40; const int SpielfeldY=20; Spielfeld_t* Spielfeld_t::instance=0; Spielfeld_t* Spielfeld_t::getInstance() { if(!instance) instance=new Spielfeld_t(SpielfeldX,SpielfeldY); return instance; } int Spielfeld_t::getSizeX() { return Spielfeld.x; } int Spielfeld_t::getSizeY() { return Spielfeld.y; } void Spielfeld_t::draw() { Screen_t* Screen=Screen_t::getInstance(); for(int x=0;x<=Spielfeld.x;x++){ Screen->set(x,0,'-'); Screen->set(x,Spielfeld.y,'-'); } for(int y=0;y<=Spielfeld.y;y++){ Screen->set(0,y,'|'); Screen->set(Spielfeld.x,y,'|'); } } //------------------------Futter_t---------------------------------------- void Futter_t::set(int x,int y) { pos.x=x; pos.y=y; } Pos_t Futter_t::getPos() { return pos; } void Futter_t::draw() { Screen_t* Screen=Screen_t::getInstance(); Screen->set(pos.x,pos.y,Zeichen); } //------------------------Snake_t---------------------------------------- void Snake_t::set(int x, int y, int laenge, char koerper,char kopf) { pos.clear(); Pos_t p; p.x=x; p.y=y; pos.push_front(p); Laenge=laenge; Koerper=koerper; Kopf=kopf; } void Snake_t::move(char r) { Pos_t p=pos[0]; switch(r) { case UP: p.y-=1; break; case DOWN: p.y+=1; break; case RIGHT: p.x+=1; break; case LEFT: p.x-=1; break; } pos.push_front(p); if(pos.size()>(unsigned int)Laenge) pos.pop_back(); } void Snake_t::draw() { Screen_t* Screen=Screen_t::getInstance(); for(unsigned int i=0;i<pos.size();i++){ if(!i){ Screen->set(pos[i].x,pos[i].y,Kopf); } else{ Screen->set(pos[i].x,pos[i].y,Koerper); } } } bool Snake_t::istKollision(Futter_t &f) { return pos[0]==f.getPos(); } bool Snake_t::istAufWand() { Spielfeld_t* Spielfeld=Spielfeld_t::getInstance(); return pos[0].x==0 || pos[0].x==Spielfeld->getSizeX() || pos[0].y==0 || pos[0].y==Spielfeld->getSizeY(); } bool Snake_t::istKollision(Snake_t &s) { bool Kollision=false; for(unsigned int i=1;i<s.pos.size();i++) if(s.pos[i]==s.pos[0]) Kollision=true; return Kollision; } //------------------------Profil_t---------------------------------------- Profil_t::Profil_t(string name) : Name(name),Punkte(0) { cout<<"Profil "<<Name<<" erstellt"<<endl; } string Profil_t::getName() { return Name; } int Profil_t::getPunkte() { return Punkte; } void Profil_t::addPunkte(int n) { Punkte+=n; } void Profil_t::show() { cout<<"Spieler "<<Name<<" : "<<Punkte<<" Punkte."<<endl; } //------------------------Highscore_t---------------------------------------- void Highscore_t::Add(Profil_t *profil) { Profile.push_front(profil); } void Highscore_t::show() { int max=0; for(unsigned int i=0;i<Profile.size();i++){ if(Profile[i]->getPunkte()>max){ max=Profile[i]->getPunkte(); } } deque<Profil_t*> p; for(int r=0;r<=max;r++){ for(unsigned int i=0;i<Profile.size();i++){ if(r==Profile[i]->getPunkte()){ p.push_front(Profile[i]); } } } for(unsigned int i=0;i<p.size();i++){ cout<<i+1<<". :"; p[i]->show(); } } //------------------------main---------------------------------------- void setFutter(Futter_t &f); void showIntro(); int main() { showIntro(); srand((unsigned int)time(0)); Spielfeld_t *Spielfeld=Spielfeld_t::getInstance(); Screen_t* Screen=Screen_t::getInstance(); Screen->init(Spielfeld->getSizeX(),Spielfeld->getSizeY()); Futter_t futter; setFutter(futter); Snake_t snake; Highscore_t highscore; char key; do{ system("cls"); cout<<"Bitte geben sie ihren Namen ein :"<<endl; string name; getline(cin,name); Profil_t* profil=new Profil_t(name); highscore.Add(profil); snake.set(20,10,4,'x','O'); key=UP; while(true) { Screen->clear(); if(_kbhit()){ key=_getch(); } snake.move(key); if(snake.istKollision(futter)){ setFutter(futter); snake.fressen(); profil->addPunkte(1); } if(snake.istAufWand()){ cout<<"Snake hat die Wand gerramt !"<<endl; _getch(); system("cls"); break; } if(snake.istKollision(snake)){ cout<<"Snake hat sich angefressen !"<<endl; _getch(); system("cls"); break; } futter.draw(); snake.draw(); Spielfeld->draw(); Screen->show(); cout<<profil->getPunkte(); Sleep(100); } highscore.show(); getchar(); system("cls"); cout<<"Um das Spiel zu beenden Esc druecken !"<<endl <<"Um ein neues Spiel zu starten Enter druecken !"<<endl; }while(_getch()!=ESC); cout<<"S N A K E C L O N E\n"<<endl; _getch(); delete Screen; return 0; } void setFutter(Futter_t &f) { Spielfeld_t* Spielfeld=Spielfeld_t::getInstance(); f.set(rand()%(Spielfeld->getSizeX()-2)+2, rand()%(Spielfeld->getSizeY()-2)+2); } void showIntro() { char IntroText[]="S N A K E C L O N E\n" "\nSteuerung mit \n" "w, a, s und d"; for(int i=0;i<sizeof(IntroText);i++){ Sleep(100); cout<<IntroText[i]; } getchar(); system("cls"); }
-
Funktioniert gut! Weiter so!
Anmerkungen:
bool Snake_t::istKollision(Futter_t &f) { Pos_t p=f.getPos(); return pos[0]==f.getPos(); && pos[0].y==p.y; }
Hier willst du sicherlich das Semikolon hinter f.getPos() wegmachen. Sollte der Compiler in der Form auch nicht schlucken.
void addPunkte(int n);
Entscheide dich für eine Sprache (am besten Englisch).
Generell wäre eine Unterteilung des Codes in Header- (.h) und Implementierungsdateien (.cpp) besser, da übersichtlicher.
Bugs habe ich nur einen gefunden: Das Futter kann auch innerhalb der Schlange spawnen.
-
danke für den Beitrag