Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.05.2023, 20:38   #1
_*ViLkA*_
Пользователь
 
Регистрация: 19.03.2023
Сообщений: 10
По умолчанию Консольная змейка

Умные люди,помогите исправить часть кода который отвечает за работу хвоста змейки.Его отрисовка в 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() {};
};
_*ViLkA*_ вне форума Ответить с цитированием
Старый 03.05.2023, 23:56   #2
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

Цитата:
Сообщение от _*ViLkA*_ Посмотреть сообщение
Код:
for (int i = 1; i < tailN; i++)
		{
			tailX[i] = tailX[i - 1];
			tailY[i] = tailY[i - 1];
		}
Вот тут вы скопировали в 1 элемент 0, потом скопировали во 2 элемент 1-ый, а там уже 0-ой. Надо наоборот
Код:
for (int i = tailN - 1; i  > 0; --i)
		{
			tailX[i] = tailX[i - 1];
			tailY[i] = tailY[i - 1];
		}
macomics вне форума Ответить с цитированием
Старый 04.05.2023, 09:46   #3
_*ViLkA*_
Пользователь
 
Регистрация: 19.03.2023
Сообщений: 10
По умолчанию

macomics, переделал,но хвост всё равно не отображается в консоли(
_*ViLkA*_ вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Консольная программа ZuBy Общие вопросы Delphi 27 31.01.2014 01:21
Консольная авторизация Vallerik Общие вопросы C/C++ 0 08.01.2014 00:59
консольная программа closeAll Помощь студентам 2 24.05.2013 19:37
Консольная змейка Banner Помощь студентам 2 21.02.2011 10:22
Консольная графика в С++ xbobikx Общие вопросы C/C++ 1 07.07.2009 00:42