Chowan Temat założony przez niniejszego użytkownika |
snake pytanie odnosnie kodu » 2017-06-25 23:40:39 w innym temacie było pytanie odnośnie snake w konsoli, napisałem swojego i chciałby prosić o jakąś konstruktywną krytykę jeśli ktoś będzie miał trochę wolnego czasu. #include <iostream> #include <windows.h> #include <conio.h> #include <cstdlib> #include <ctime> #include <fstream> #include <string> #include <vector>
using namespace std; const int wysokosc = 20; const int dlugosc = 40;
struct snake { int px; int py; int ppx; int ppy; } waz; struct Jablko { int px; int py; } jablko;
void mapa( char tab[ wysokosc ][ dlugosc ] ); void draw( char tab[ wysokosc ][ dlugosc ] ); bool moves( char tab[ wysokosc ][ dlugosc ], char & kierunek, snake & glowa ); bool losuj( char tab[ wysokosc ][ dlugosc ], int & wynik ); void bodymove( char tab[ wysokosc ][ dlugosc ], vector < snake >& cialo, const bool & czyzjedzono ); void save( const int & wynik ); void load();
int main() { while( 1 ) { srand( time( NULL ) ); int score = 0; char klawisz = 'w'; waz = { wysokosc / 2, dlugosc / 2 }; vector < snake > body( 3 ); char tab[ wysokosc ][ dlugosc ]; mapa( tab ); for( int i = 0; i < body.size(); i++ ) { body[ i ].px = waz.px + i + 1; body[ i ].py = waz.py; tab[ body[ i ].px ][ body[ i ].py ] = 'o'; } jablko = {( rand() %( wysokosc - 2 ) ) + 1,( rand() %( dlugosc - 2 ) ) + 1 }; tab[ waz.px ][ waz.py ] = 'O'; tab[ jablko.px ][ jablko.py ] = '@'; draw( tab ); while( 1 ) { if( moves( tab, klawisz, waz ) == false ) break; bodymove( tab, body, losuj( tab, score ) ); system( "cls" ); draw( tab ); score++; } cout << "GameOver!!!" << " Twoj wynik to: " << score << endl; load(); save( score ); cout << " ESC aby zakonczyc, inny przycisk aby zaczac od nowa\n"; if( getch() !=( char ) 27 ) { cout << "Zaczynamy od nowa"; Sleep( 2000 ); } else break; } return 0; } void mapa( char tab[ wysokosc ][ dlugosc ] ) { for( int i = 0; i < wysokosc; i++ ) { for( int j = 0; j < dlugosc; j++ ) { if( i == 0 || i == wysokosc - 1 ) tab[ i ][ j ] = '_'; else if( j == 0 ||( j == dlugosc - 1 ) ) tab[ i ][ j ] = '|'; else tab[ i ][ j ] = ' '; } } } void draw( char tab[ wysokosc ][ dlugosc ] ) { for( int i = 0; i < wysokosc; i++ ) { for( int j = 0; j < dlugosc; j++ ) { cout << tab[ i ][ j ]; } cout << endl; } } bool moves( char tab[ wysokosc ][ dlugosc ], char & kierunek, snake & glowa ) { glowa.ppx = glowa.px; glowa.ppy = glowa.py; if( kbhit() ) { Sleep( 200 ); kierunek = getch(); switch( kierunek ) { case 'a': waz.py--; break; case 'w': waz.px--; break; case 's': waz.px++; break; case 'd': waz.py++; break; default: waz.px++; break; } if(( tab[ waz.px ][ waz.py ] != 'o' ) && !(( waz.px == 0 || waz.px == wysokosc - 1 || waz.py == 0 || waz.py == dlugosc - 1 ) ) ) { tab[ waz.px ][ waz.py ] = 'O'; return true; } else return false; } else { Sleep( 200 ); switch( kierunek ) { case 'a': waz.py--; break; case 'w': waz.px--; break; case 's': waz.px++; break; case 'd': waz.py++; break; default: waz.px++; break; } if(( tab[ waz.px ][ waz.py ] != 'o' ) && !(( waz.px == 0 || waz.px == wysokosc - 1 || waz.py == 0 || waz.py == dlugosc - 1 ) ) ) { tab[ waz.px ][ waz.py ] = 'O'; return true; } else return false; } } bool losuj( char tab[ wysokosc ][ dlugosc ], int & wynik ) { if( waz.px == jablko.px && waz.py == jablko.py ) { while( tab[ jablko.px ][ jablko.py ] != ' ' ) { jablko = {(( rand() %( wysokosc - 2 ) ) + 1 ),(( rand() %( dlugosc - 2 ) ) + 1 ) }; } tab[ jablko.px ][ jablko.py ] = '@'; wynik += 10; return 1; } else return 0; } void load() { ifstream plik; plik.open( "snake.txt" ); if( plik.is_open() ) { string text; getline( plik, text ); cout << text << endl; plik.close(); } else if( plik.fail() ) { cout << "Tworze plik z highscore"; ofstream plika( "snake.txt" ); plika << "0"; plika.close(); } } void save( const int & wynik ) { fstream plik; plik.open( "snake.txt", ios::in | ios::out ); int a; plik >> a; while( plik.fail() ) { plik.clear(); plik.ignore(); plik >> a; } plik.close(); plik.open( "snake.txt", ios::in | ios::out ); if( wynik > a ) plik << "Najlepszy wynik do tej pory: " << wynik; plik.close(); } void bodymove( char tab[ wysokosc ][ dlugosc ], vector < snake >& cialo, const bool & czyzjedzono ) { cialo[ cialo.size() - 1 ].ppx = cialo[ cialo.size() - 1 ].px; cialo[ cialo.size() - 1 ].ppy = cialo[ cialo.size() - 1 ].py; for( int i = cialo.size() - 1; i > 0; i-- ) { cialo[ i ].px = cialo[ i - 1 ].px; cialo[ i ].py = cialo[ i - 1 ].py; tab[ cialo[ i ].px ][ cialo[ i ].py ] = 'o'; } cialo[ 0 ].px = waz.ppx; cialo[ 0 ].py = waz.ppy; tab[ cialo[ 0 ].px ][ cialo[ 0 ].py ] = 'o'; if( czyzjedzono ) { cialo.push_back( { cialo[ cialo.size() - 1 ].ppx, cialo[ cialo.size() - 1 ].ppy } ); tab[ cialo[ cialo.size() - 1 ].ppx ][ cialo[ cialo.size() - 1 ].ppy ] = 'o'; } else tab[ cialo[ cialo.size() - 1 ].ppx ][ cialo[ cialo.size() - 1 ].ppy ] = ' '; }
|
|
latajacaryba |
» 2017-06-26 01:45:59 Nazwy zmiennych są nieintuicyjne (bez komentarza nigdy nie wiedziałbym co robi ppx czy ppy). Kiedy IDE podpowiada nazwy, nie ma co bać stosowania długich, np. PoprzedniaPozycjaX No i dlaczego nazwy raz są po polsku a raz po angielsku? Poza tym ja bym zrobił coś tego typu, że jak idziesz wężem w dół, to nie możesz nacisnąć "W" (w sensie to nic nie daje). Żeby to wykonać możesz np. sprawdzać kierunek ruchu węża: enum KierunekWeza { gora, prawa, dol, lewa };
// poruszanie + sprawdzanie czy nie ma kolizji |
No właśnie. Funkcje troche zbyt duze. Może warto zrobić coś takiego: void RuchWeza( Snake & Waz ) { IdzPrzedSiebie( Waz ); if( CzyBylaKolizja( Waz ) == true ) KoniecGry(); }
Rozbij to na mniejsze części. Powinny być jak najmniej zależne od siebie. No i ostatnia rzecz... to nie jest w tym przypadku jakiś duży błąd, zmienne deklarujemy poza pętlami. Ale generalnie to fajnie Ci to wyszło :D |
|
Chowan Temat założony przez niniejszego użytkownika |
» 2017-06-26 08:14:01 Po pierwsze dzięki za odpowiedź. Z tymi nazwami to nie wiem czemu tak wyszło :), ale następnym razem od razu zacznę od angielskich. Nazwy nieintuicyjne, bo pierwsze raz robię coś co wykracza poza 50 linijek i taki jakiś zły nawyk, w funkcjach starałem się dawać w miarę jasne. A te ppx to nie mogłem przez dłuższy czas ustawić sterowania ciałem i siedziałem zdenerwowany i jak w końcu na coś wpadłem to jakoś tak się ustawiło w przypływie euforii. Co do enum to widziałem coś, ale nie do końca rozumiałem jak to działać by miało, a jak już gdzieś znalazłem to było poruszani zrobione i nie chciałem zepsuć :D. Ustawiłem, że jak wraca na ciało to koniec gry.
Jeśli chodzi o zmienne za pętlami to o te za pierwszym wywołaniem while w int main()? Bo miałem je globalnie ustawione, ale widziałem że to spotka się z delikatna krytyką. Przestawiłem je do maina i ustawiłem pętle, żeby można było zaczynać od początku bez wyłączania gry.
Ogólnie będę zaczynał teraz rozdziały z projektowaniem obiektowym u praty i będę chciał sukcesywnie przenosić to na klasy i funkcje do plików nagłówkowych to postaram się wtedy przepisać to uwzględniając Twoje porady.
|
|
latajacaryba |
» 2017-06-26 12:18:25 enum KierunekWeza { Gora, Dol, Lewa, Prawa }
struct Waz { int MapaPozycjaX int MapaPozycjaY; Kierunek KierunekRuchu; ... }
CzyZmienicKierunekRuchu = true;
switch( Waz.KierunekRuchu ) { case Gora: if( klawisz == 's' ) CzyZmienicKierunekRuchu = false; break; }
A te ppx to nie mogłem przez dłuższy czas ustawić sterowania ciałem i siedziałem zdenerwowany i jak w końcu na coś wpadłem to jakoś tak się ustawiło w przypływie euforii. |
https://youtu.be/nXwDEL-ivis |
|
pekfos |
» 2017-06-26 12:25:03 zmienne deklarujemy poza pętlami. |
Bez sprecyzowania - bzdury. Zmienne powinny mieć możliwie mały zakres widoczności, więc jak najbardziej mogą być utworzone w pętli. |
|
latajacaryba |
» 2017-06-26 12:32:18 @up
To przepraszam, gdzieś kiedyś wyczytałem, że tak być powinno. Zedytuje wypowiedź. |
|
Monika90 |
» 2017-06-26 14:38:42 Zakres widoczności zmiennych powinien być tak mały jak to możliwe, chyba że masz powód by tak nie było. Np. chcesz uniknąć zbędnej dynamicznej alokacji pamięci, więc deklarujesz std::string przed pętlą. |
|
« 1 » |