• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

[C++] Gra Snake, długość węża.

Object Storage Arubacloud
0 głosów
653 wizyt
pytanie zadane 27 kwietnia 2017 w C i C++ przez Antero00 Gaduła (3,670 p.)
Witam, Jestem w trakcie pisanie gry Snake w konsoli i zastanawiam się, w jaki sposób napisać, aby po "zjedzeniu owoca" wąż zwiększał swoją długość. Prosiłbym o jakieś wskazówki jak "ugryźć" ten problem. Oczywiście nie chcę żadnych gotowców.

3 odpowiedzi

+2 głosów
odpowiedź 27 kwietnia 2017 przez Eryk Andrzejewski Mędrzec (164,260 p.)
edycja 27 kwietnia 2017 przez Eryk Andrzejewski

Ja Ci dam pewną podpowiedź, kiedyś na to wpadłem (znając życie jeszcze z kilka milionów ludzi przede mną) i zastosowałem w swoim Snake'u.

Jeśli chodzi o poruszanie się węża, to bez sensu jest zmieniać pozycję wszystkich jego elementów. Wystarczy usunąć ostatni element (koniec ogona), a na początek kontenera (np. std::deque) wrzucić nowy element ("nową głowę" laugh) zgodnie z kierunkiem poruszania się węża. A przy zjadaniu owoca - sytuacja jest analogiczna, tylko że nie usuwasz końca ogona.

1
komentarz 27 kwietnia 2017 przez Wiciorny Ekspert (269,810 p.)
no z drugiej strony, ZNACZNIE oszczędzamy pamięć, upraszczamy i przyspieszamy nie tyle sam kod co działanie,  niż np przy przesuwaniu wszystkich elementów.
komentarz 27 kwietnia 2017 przez Magicone Nałogowiec (45,100 p.)
Wiciorny, niekoniecznie, zależy od tego jak w ogóle przeprowadzasz translację i w jaki sposób wyświetlasz sprity.
komentarz 27 kwietnia 2017 przez Wiciorny Ekspert (269,810 p.)
Obudź logikę :D nie istnieje przypadek dla którego przestawienie n+1 wartości komórek pamięci np, jest korzystniejsze niż n operacji
+1 głos
odpowiedź 27 kwietnia 2017 przez Evelek Nałogowiec (28,960 p.)
Wykorzystaj kontener z STL, który zrobi to najszybciej - elementy będą dodawane z jednej strony, więc pasującymi kontenerami są deque, list, forward_list. Zapoznaj się jakie metody możesz wykonywać na takich kontenerach.
0 głosów
odpowiedź 2 maja 2017 przez Antero00 Gaduła (3,670 p.)

Muszę jeszcze prosić o jakieś wskazówki dotyczące programu, próbuję wykorzystać kontener deque lecz nadal mam problem. 

Czy powinienem przerobić ten program od początku z wykorzystaniem kontenera stl ? 

O to mój kod: 

#include <iostream>
#include <ctime>
#include <conio.h>
#include <deque>

const int width = 40;
const int height = 20;

class Snake
{
	int xFood, yFood, xHead, yHead, Score = 0;
	enum Direction { LEFT, RIGHT, UP, DOWN };
	Direction Dir;
	//std::deque <int> x;
	//std::deque <int> y;
	int LengthSnake = 0;

public:
	bool Gameover;
	void StartGame();
	void CreateMap();
	void CreateFood();
	void SnakePosition();
	void ChangeDirection();
	void MoveSnake();
	
};
//*************************************************************
int main()
{
	srand(time(NULL));
	Snake s1;
	s1.StartGame();
	
	while (!s1.Gameover)
	{
		system("cls");
		s1.CreateMap();
		s1.ChangeDirection();
		s1.MoveSnake();
	}
	system("pause");
	return 0;
}
//*************************************************************

void Snake::StartGame()
{
	Gameover = false;
	CreateFood();
	SnakePosition();
}

void Snake::CreateMap()
{
	for (int i = 0; i < width; i++)
		std::cout << char(219);  // up frame
	std::cout << std::endl;

	for (int i = 0; i < height; i++)
	{
		for (int j = 0; j < width - 1; j++)
		{
			if (j == 0)
				std::cout << char(219);  // left frame

			else if (j == xFood && i == yFood)
				std::cout << char(254);

			else if (j == xHead && i == yHead)
				std::cout << char(219);

			else if (j > 0 || j < width - 1)
				std::cout << char(255);

			else if (j == width)
				std::cout << char(219);
		}
		std::cout << char(219);  // right frame
		std::cout << std::endl;
	}
			
	for (int i = 0; i < width; i++)
		std::cout << char(219);  // down frame
	std::cout << std::endl << std::endl;
	std::cout << "Your Score: " << Score << std::endl << std::endl;
}

void Snake::CreateFood()
{
	xFood = rand() % (width - 1) + 1;
	yFood = rand() % (height - 1) + 1;
}

void Snake::SnakePosition()
{
	xHead = width / 2;
	yHead = height / 2;
}

void Snake::ChangeDirection()
{
	if (_kbhit())
	{
		switch (_getch())
		{
		case 'a':
			Dir = LEFT;
			break;
		case 'd':
			Dir = RIGHT;
			break;
		case 'w':
			Dir = UP;
			break;
		case 's':
			Dir = DOWN;
			break;
		case 'x':
			Gameover = true;
			break;
		}
	}
}

void Snake::MoveSnake()
{
	switch (Dir)
	{
	case LEFT:
		xHead--;
		break;

	case RIGHT:
		xHead++;
		break;

	case UP:
		yHead--;
		break;

	case DOWN: 
		yHead++;
		break;
	default:
		break;
	}

	if (xHead == xFood && yHead == yFood)
	{
		CreateFood();
		Score += 10;
	}

	if (xHead >= width - 1 || xHead <= 0 || yHead < 0 || yHead >= height)
		Gameover = true;
}

 

komentarz 3 maja 2017 przez Knayder Nałogowiec (37,640 p.)
Po pierwsze, to podziel program na jakieś klasy itp., bo tak to się zaczniesz gubić w kodzie.
Po drugie, nie powiedziałeś z czym masz problem.

Po trzecie: Zastosuj się do porad Eryka. Stwórz vector<snakePart> snake;. Za każdym przejściem pętli gry, dodawaj na początku jeden element, z pozycją wyliczoną na podstawie kierunku ruchu: snake.insert( snake.begin(), newSnakePart );
Potem usuń ostatni element JEŻELI owoc nie został zjedzony w danym ticku:
if(!growing)
   snake.pop_back();

Podobne pytania

0 głosów
0 odpowiedzi 104 wizyt
pytanie zadane 21 listopada 2019 w C i C++ przez Wiktor Michalski Początkujący (430 p.)
0 głosów
0 odpowiedzi 175 wizyt
0 głosów
0 odpowiedzi 141 wizyt

92,568 zapytań

141,424 odpowiedzi

319,634 komentarzy

61,956 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...