Умные люди,помогите исправить часть кода который отвечает за работу хвоста змейки.Его отрисовка в showMap(),а сама логика в tailLogic().Я понимаю что надо сделать изменение координат при движении,но не пойму как написать.Буду благодарен за помощь)))
Код:
#include <iostream>
#include <Windows.h>
#include <conio.h>
#include <fstream>
#include <string>
#include <algorithm>
using namespace std;
#define width 30 // ширина
#define heigth 20 // длина
#define fence '#' // ограждение игрового поля
#define field ' ' // само поле
#define head 'O' // голова змейки
#define tail 'o' // хвост змейки
#define fruit 'F' // фрукт для змейки
enum KEY { STOP = 0, UP = 72, DOWN = 80, LEFT = 75, RIGHT = 77, SPACE = 32, ESC = 27 }; // определение клавиш
bool gameOver; // для конца игры
int score; // количество очков
class Snake
{
protected:
int x, y; // координаты змейки
int fruitX, fruitY; // координаты фрукта
int tailX[100], tailY[100]; // массивы для хранения координат хвоста
int tailN; // размер хвоста
public:
Snake() { setup(); }
void gotoxy(int xPos, int yPos) // работа с курсором
{
COORD scrn;
HANDLE hOuput = GetStdHandle(STD_OUTPUT_HANDLE); // создание "ручки" для вывода на экран консоли текста и прочего
scrn.X = xPos;//
scrn.Y = yPos;//-присваем значения
SetConsoleCursorPosition(hOuput, scrn);// ставим курсор на нужную позицию
Sleep(50);
}
void cursor() // для того что бы курсор не бегал по экрану
{
auto handle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO structCursorInfo;
GetConsoleCursorInfo(handle, &structCursorInfo);
structCursorInfo.bVisible = FALSE;
SetConsoleCursorInfo(handle, &structCursorInfo);
}
void setup() // здесь задаем изначальные данные
{
gameOver = false; // игра не окончена
x = width / 2 - 1; // змейка появляется в середине карты
y = heigth / 2 - 1;
fruitX = 1 + rand() % (width - 2); // фрукт появляется в случайном месте
fruitY = 1 + rand() % (heigth - 2);
score = 0; // очков изначально 0
}
void showMap()
{
for (int i = 0; i < width + 1; i++) { cout << fence; } cout << endl; // закрaшивание верхней границы
for (int i = 0; i < heigth; i++) // цикл для заполнения поля нужными символами
{
for (int j = 0; j < width; j++)
{
if (j == 0 || j == width - 1) { cout << fence; } // угловые элементы поля
if (i == y && j == x) { cout << head; } // голова змейки
else if (i == fruitY && j == fruitX) { cout << fruit; } // фрукт
else
{
bool print = false;
for (int k = 0; k < tailN; k++) // проходим циклом по хвосту
{
if (tailX[k] == j && tailY[k] == i) // если координаты хвоста равны координатам на карте
{
print = true;
cout << tail; // выводим хвост
}
}
if (!print) { cout << field; } // закрашиваем поле
}
}
cout << endl;
}
for (int i = 0; i < width + 1; i++) { cout << fence; } cout << endl; // закрашивание нижней границы
cout << endl << "Score : " << score << endl;
gotoxy(0, 0); // ставим курсор в нужное место
}
void snakeMove() // метод для движения змейки по экрану
{
if (_kbhit()) // в буффере проверяем нажата ли клавиша
{
switch (_getch()) // ожидание нажатия клавиши
{
case LEFT: {x--; break; }
case RIGHT: {x++; break; }
case UP: {y--; break; }
case DOWN: {y++; break; }
case ESC: {gameOver = true; break; }
}
}
showMap(); // показываем карту
}
void tailLogic() // метод который будет обрабатывать элементы хвоста
{
if (x == fruitX && y == fruitY) // если координаты головы змейки равны координатам фрукта
{
score += 10; // добавляем 10 очков
fruitX = 1 + rand() % (width - 2); // и показываем фрукт в новой точке
fruitY = 1 + rand() % (heigth - 2);
tailN ++; // увеличиваем хвост
}
///////////////////////////////////////////////////////////////////////////// косяк с хвостом где-то тут
for (int i = 1; i < tailN; i++)
{
tailX[i] = tailX[i - 1];
tailY[i] = tailY[i - 1];
}
int pastX = tailX[0]; // предыдущие позиции по Х/У
int pastY = tailY[0]; // в них помещаем первый элемент хвоста
int past2X, past2Y; // сюда помещаем следующие элементы хвоста
tailX[0] = x; // первым элементов хвоста будет голова
tailY[0] = y;
for (int i = 1; i < tailN; i++) // проходим по хвосту циклом не затрагивая 1 элемент так как он уже известен
{
past2X = tailX[i - 1];
past2Y = tailY[i - 1];
tailX[i] = pastX; // этим циклом обрабатываем весь хвост, получая координаты первого и последущих элементов хвоста и перезаписываем
tailY[i] = pastY;
pastX = past2X;
pastY = past2Y;
}
/////////////////////////////////////////////////////////////////////////
for (int i = 0; i < tailN; i++) // проходим по хвосту циклом
{
if (tailX[i] == x && tailY[i] == y) // если змейка съела хвост
{
gameOver = true; // игра заканчивается
}
}
}
void logicGame() // метод для обработки соприкосновения с границей поля
{
if (x >= width - 1) { x = 0; }
else if (x < 0) { x = width - 2; }
if (y >= heigth) { y = 0; }
else if (y < 0) { y = heigth - 1; }
}
void logic() // метод для обощения работы
{
tailLogic();
logicGame();
snakeMove();
}
~Snake() {};
};