#include <iostream.h>
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <ctime>
using namespace std;
class pos { //klasa pozycji (współrzędnych)
public:
int x;
int y;
pos () {x = 0; y = 0;} //domyślne wartości: x=0, y=0
};
class snake { //klasa węża
public:
pos main[2964];
int length;
void eat(pos p) { //funkcja zmienia pozycję węża na odpowiednią po zjedzeniu jabłka o pozycji z argumentu
length++; //zwiększamy długość węża
for(int i=(length-1); i>0; i--) main[i] = main[i-1]; //przesuwamy pozycje na odpowiednie miejsca w nowym wężu
main[0]=p; //początkiem nowego węża będzie pozycja zjedzonego właśnie jabłka
}
void move(pos p) { //funkcja zmienia pozycję węża na odpowiednią po ruchu na pozycję z argumentu
for(int i=(length-1); i>0; i--) main[i] = main[i-1]; //przesuwamy pozycje na odpowiednie miejsca w nowym wężu
main[0] = p; //początkiem nowego węża będzie oczywiście pozycja, na którą przesunie się głowa
}
bool isHere(pos p) { //funkcja sprawdza, czy w ciele węża znajduje się pozycja podana jako argument
for(int i=0; i<length; i++) {
if(main[i].x==p.x && main[i].y==p.y) return true;
}
return false;
}
};
class board { //klasa planszy
public:
char main[38][78]; //plansza ma wymiary 38 (w pionie) x 78 (w poziomie)
void make(snake s, pos apple) { //funkcja kodująca planszę na podstawie ciała węża i pozycji jabłka
for(int i=0; i<38; i++) {
for(int j=0; j<78; j++) main[i][j] = 0; //czyścimy nową planszę
}
for(int i=0; i<s.length; i++) main[s.main[i].x][s.main[i].y] = 2; //kodujemy węża na planszy; kod części ciała węża to 2
main[apple.x][apple.y] = 1; //kodujemy jabłko na planszy; kod jabłka to 1
}
};
pos randomApplePosition(snake s) { //funkcja losuje pozycję jabłka tak, aby nie wylosować pozycji, którą zajmuje wąż
pos p; //tworzymy sobie tymczasową zmienną do przechowywania pozycji
while(true) {
srand(static_cast<int>(time(NULL))); //ziarnem losowości będzie aktualny czas
p.x = rand()%38; //losujemy część pionową pozycji
p.y = rand()%78; //losujemy część poziomą pozycji
if(!s.isHere(p)) return p; //jeśli ciało węża nie zawiera wylosowanej przez nas pozycji, możemy ją zwrócić
}
}
void draw(board b) { //funkcja rysuje planszę na ekranie
system("cls"); //czyścimy ekran
cout<<"--------------------------------------------------------------------------------"; //rysujemy górną belkę planszy
for(int i=0; i<38; i++) {
cout<<"|"; //rysujemy lewą pionową belkę planszy
for(int j=0; j<78; j++) {
if(b.main[i][j]==0) cout<<" "; //jeśli na tej pozycji na planszy nic nie ma, zostawiamy oczywiście na ekranie puste miejsce
else if(b.main[i][j]==2) cout<<"+"; //jeśli na tej pozycji na planszy jest część ciała węża, rysujemy ją jako plus
else cout<<"*"; //jeśli na tej pozycji na planszy jest jabłko, rysujemy je jako gwiazdka
}
cout<<"|"; //rysujemy prawą pionową belkę planszy
}
cout<<"--------------------------------------------------------------------------------"; //rysujemy dolną belkę planszy
}
const unsigned char KEY_UP = 72; //kod klawisza odpowiadającego za ruch w górę; domyślnie - górna strzałka
const unsigned char KEY_LEFT = 75; //kod klawisza odpowiadającego za ruch w lewo; domyślnie - lewa strzałka
const unsigned char KEY_RIGHT = 77; //kod klawisza odpowiadającego za ruch w prawo; domyślnie - prawa strzałka
const unsigned char KEY_DOWN = 80; //kod klawisza odpowiadającego za ruch w dół; domyślnie - dolna strzałka
int main()
{
board b; //tworzymy planszę
for(int i=0; i<38; i++) {
for(int j=0; j<78; j++) b.main[i][j] = 0; //czyścimy naszą początkową planszę
}
snake s; //tworzymy węża
s.length = 1; //początkowa długość naszego węża to oczywiście 1
pos head; //tworzymy pozycję, która zawsze będzie oznaczać głowę węża; będziemy jej używać przy modyfikacjach po naciśnięciu klawisza
pos apple = randomApplePosition(s); //tworzymy jabłko i losujemy jego pozycję
b.main[apple.x][apple.y] = 1; //kodujemy jabłko na planszy
unsigned char key; //tworzymy zmienną na pobierany kod klawisza
unsigned char dir=0; //tworzymy zmienną oznaczającą kierunek ruchu węża
int score = 0; //początkowy wynik to oczywiście 0
b.make(s, apple); //kodujemy planszę
draw(b); //rysujemy planszę
while(true) {
key = _getch(); //pobieramy pierwszy kod klawisza; jest on stały i do niczego nam się nie przyda
key = _getch(); //pobieramy drugi, właściwy kod klawisza
switch(key) {
case KEY_UP: if(dir==KEY_DOWN) continue; dir=key; if(head.x!=0) head.x--; break; //jeśli gracz nie próbuje wykonać ruchu w kierunku przeciwnym do aktualnego kierunku ruchu, sprawdzamy, czy może się jeszcze ruszyć w górę - jeśli tak, przesuwamy pozycję oznaczającą głowę; warte zauważenia jest to, że jeśli nie może wykonać ruchu w górę, pozycja głowy nie zmieni się, a wtedy program zareaguje tak, jakby gracz wszedł sam na siebie, a więc po chwili zakończy swoje działanie
case KEY_LEFT: if(dir==KEY_RIGHT) continue; dir=key; if(head.y!=0) head.y--; break; //jw. - ruch w lewo
case KEY_RIGHT: if(dir==KEY_LEFT) continue; dir=key; if(head.y!=77) head.y++; break; //jw. - ruch w prawo
case KEY_DOWN: if(dir==KEY_UP) continue; dir=key; if(head.x!=37) head.x++; //jw. - ruch w dół
}
switch(b.main[head.x][head.y]) { //sprawdzamy, co znajduje się na nowej pozycji głowy węża
case 0: s.move(head); b.make(s, apple); draw(b); break; //jeśli nic tam nie ma, zwyczajnie przesuwamy węża; później kodujemy planszę i rysujemy ją
case 1: score++; s.eat(head); apple = randomApplePosition(s); b.make(s, apple); draw(b); break; //jeśli jest tam jabłko, zwiększamy wynik, zwiększamy długość węża i przesuwamy go oraz losujemy pozycję jabłka; później kodujemy planszę i rysujemy ją
case 2: Sleep(3000); system("cls"); cout<<"Niestety zakonczyles gre. Twoj wynik to "<<s.length<<"."<<endl<<"Gratulacje! ;)"; getchar(); return 0; //jeśli jest tam ciało węża, oznacza to, że gracz wszedł sam na siebie; czekamy 3 sekundy, wypisujemy na ekranie komunikat z wynikiem, czekamy na naciśnięcie klawisza i kończymy działanie programu
}
}
return 0; //formalność
}