Skręcanie w Snake'u[C++]

0

Witam,
Niedawno postanowiłem spróbować napisać sobie snake'a w C++ (tylko konsola, żadnych dodatkowych bibliotek - bo po co? nie potrzebuję wyrafinowanej grafiki). Ot tak, dla rozrywki :). Moja wiedza nie jest jeszcze zbyt duża, ale mimo to spróbować nigdy nie zawadzi.
Dodam jeszcze, że na ekranie wyświetlam poszczególne "klatki" gry w taki sposób:

  1. Mam stringa, w którym trzymam mój "ekran" - czyli to co mam akurat wyświetlić,
  2. Do tego stringa dodaję co jakiś czas węża - posuniętego o jeden znak dalej względem tego wyświetlanego w poprzedniej "klatce"
  3. Między wyświetleniami oczywiście czyszczę całą konsolę.

No ok. Wszystko fajnie, tylko że nie do końca wiem jak zrobić skręcanie. Pomysł niby jakiś jest, ale nie bardzo wiem jak to przełożyć na kod (to dlatego że mój wąż to po prostu string):

  1. W każdej "klatce" zapamiętuję w tablicy pozycję w konsoli każdego z fragmentów węża (każdego znaku '*'),
  2. a w następnej przesuwam każdy fragment tak, by znalazł się na tej pozycji, na której stał dalszy fragment w poprzedniej "klatce".
  3. do tego jeśli gracz wciśnie jakiś klawisz, to "głowa" węża kieruje się w odpowiednim kierunku, a reszta fragmentów po prostu "wędruje" za nią - dzięki kodowi z dwóch pierwszych punktów.

Mój program składa się z kilku plików, ale sama gra znajduje się w pliku "GRA.cpp", więc to tego pliku zawartość tu wkleję:

 #include <iostream>
#include <string>
using namespace std;

#include <conio.h>
#include <windows.h> // Dla Sleep()

void Gra()
{
    enum kierunki {prawo, lewo, gora, dol};
    kierunki kierunek = prawo; // Domyœlnie posuwamy snake'a w prawo

    string ekran;
    ekran.insert(0, 80, ' ');
    ekran.insert(ekran.length(), 80, '-');
    ekran.insert(ekran.length(), 1676, ' ');
    ekran.insert(ekran.length(), 80, '-');

    string snake = "***]";
    ekran.insert(961, snake);

    cout << ekran;

    while(1)
    {
        string::size_type pozycja = ekran.find('*');
        ekran.erase(pozycja, snake.length());

        Sleep(50);

        system("cls");

        if(kbhit()) // Sprawdzamy, czy jest co czytaæ (czy naciœniêto jakiœ klawisz)
        {
            char znak = getch();

            switch(znak)
            {
                case 224:
                    znak = getch();
                    switch(znak)
                    {
                        case 72: // GÓRA
                            kierunek = gora;
                        break;

                        case 80: // DÓ£
                            kierunek = dol;
                        break;

                        case 75: // LEWO
                            kierunek = lewo;
                        break;

                        case 77: // PRAWO
                            kierunek = prawo;
                        break;
                    }
                break;
            }
        }

        switch(kierunek)
        {
            case gora:

            break;

            case dol:
            break;

            case lewo:
            break;

            case prawo:
                if((pozycja + 1) % 80) { ekran.insert(pozycja + 1, snake); } // Przesuwamy snake'a o jeden znak dalej               // To po prostu przesuwa snake'a, ale wcale go nie skręca
                else
                {
                    pozycja -= 79; // Cofamy do pocz¹tku lini
                    ekran.insert(pozycja + 1, snake); // i rpzesuwamy tam snake'a
                }
            break;
        }
}

Obawiam się, że coś takiego może być na razie ponad miarę moich możliwości. No ale zobaczymy, może uda mi się to skończyć. Liczę na waszą pomoc. Od razu mówię że wolałbym dostać poradę, niż link do strony z kodem czyjegoś snake'a :P

0

Nie byłoby Ci wygodniej zrobić snake'a jako tablicę punktów?
W każdym razie byłoby to logiczniejsze.

0

Hmm. Najprostszy ruch węża to usuwanie ostatniego elementu z vectora i dodanie go na początek. Wtedy przesuwasz tylko 1 element zachowując ciągłość węża :) Oczywiście taki kontener przechowuje każdy kawałek węża, który jest np strukturą z coordami i kierunkiem ruchu.

0

Jest późno, więc naklepałem odrobinę kodu.
http://ideone.com/VPRsp1

Direction{ UP, DOWN, LEFT, RIGHT };
Map{
    Map(width, height);
    width()->size_t;
    height()->size_t;
};

Snake{
    BodyElement{ sign, x, y };
    Snake(direction, bodyElement);
    direction()->Direction;
    setDirection(direction);
    head()->BodyElement &;
    head const()->const BodyElement &;
    addBodyElement(sign);
    /*move(); <- meh */
}

Drawer{
    Drawer(map);
    snake(const &snake);
    operator()();
}

I mały test(mając obiekty Map(5, 5), snake(DOWN, BodyElement{'x', 0, 0}), Drawer(map)):

snake.addBodyElement('a');
snake.addBodyElement('b');
snake.setDirection(RIGHT);
snake.addBodyElement('c');
snake.addBodyElement('d');
snake.setDirection(UP);
snake.addBodyElement('e');
snake.addBodyElement('f');
draw.snake(snake);
draw();

out:

x f  
a e  
bcd  
     
     

1 użytkowników online, w tym zalogowanych: 0, gości: 1