[Complete el juego de la serpiente con pensamiento orientado a objetos C++ y STL]

1. Introducción

1.1 Propósito

No me importaba mucho el conocimiento de STL en el pasado. Recientemente, sentí que había demasiados lugares donde se usaba STL en los códigos de ingeniería en el trabajo. No lo entendía. Entonces pensé que podría escribir una serpiente codiciosa para aprender y vender ahora, y profundizar la imagen.

1.2 Recomendaciones

Se recomienda que los estudiantes que no estén familiarizados con STL puedan revisar STL antes de leer este artículo.

1.3 Entorno de desarrollo

Idioma: C++
Entorno: Visual Studio 2022, Windows

2. Pantalla de logros

Sin marcas de tinta, primero muestra los resultados.
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

3. Requisitos del proyecto

1. Inicialice el juego, genere mapas, serpientes y comida
2. Las serpientes crecen más después de comer comida
3. Las serpientes no pueden moverse al revés 4.
Inmediatamente produzca nuevas después de comer comida
5. Registre la cantidad de comida consumida (puntuación)
6 .La comida no se puede generar en el cuerpo de la serpiente
7. La serpiente no puede golpearse a sí misma
8. Establecer la dificultad del juego
9. Si la serpiente golpea la pared, el juego termina directamente

4. Diseño detallado

4.1 Resumen

Como se mencionó anteriormente, está escrito con pensamiento orientado a objetos, por lo que debe generar serpientes, comida y puntos. ¿Por qué no mapas? Porque primero uso el método de dibujar puntos y luego uso puntos para dibujar un mapa cuadrado. Y también puedes usar puntos para dibujar serpientes y comida.

Serpientes:

inserte la descripción de la imagen aquí

Categoría de alimentos:
inserte la descripción de la imagen aquí

clase de punto:
inserte la descripción de la imagen aquí

4.2 Inicialización

4.2.1 Mapa

Antes de presentar cómo inicializar el mapa, primero comprendamos cómo generar un pequeño cuadrado con código en la terminal.
Así es, solo imprima cout, pero quiero imprimirlo en una coordenada conocida.
Entonces necesitas usar el posicionamiento del cursor:

void gotoxy(int x, int y) //光标定位
{
    
    
	COORD pos = {
    
     x,y };
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}

Luego, simplemente imprima los cuadrados, use los símbolos en el método de entrada de perro determinado:
inserte la descripción de la imagen aquí
luego puede imprimir los cuadrados en coordenadas específicas, y luego puede continuar imprimiendo mapas con ancho y alto personalizados.
需要强调一点,终端的光标的高 = 2 * 宽,所以我们方块的坐标想在终端输出(4,4)的位置,就需要在代码中用(8,4)来代替。

4.2.1 Serpientes y comida

Luego sigamos entendiendo cómo inicializar la serpiente y la comida.La inicialización debe generarse con coordenadas aleatorias, lo que requiere el uso de la función rand(), y luego se puede generar un número entero en el intervalo [a,b]:

randNum = rand() % (b - a + 1) + a;

Ha pasado tanto tiempo desde que simplemente puedes generar aleatoriamente una cabeza de serpiente y comida en la terminal.

Para toda la serpiente, uso contenedores vector< pair< int, int > >para almacenar coordenadas, y para la comida, uso pair< int, int >

4.3 El cuerpo de la serpiente se vuelve más largo después de comer la comida

Primero, debe darse cuenta de la lógica de movimiento de la serpiente: inicialice la serpiente para que se mueva hacia la derecha, asumiendo las coordenadas de la cabeza de la serpiente (x, y), luego agregue esta coordenada (x-1, y) al elemento de cola de la vector, luego elimine el elemento principal y "插尾删头".

这里我们还需要定义一个oldSnack vector来打印空格,来抹去上一次蛇的身体,不然蛇是会一直覆盖,你会发现,蛇尾看起来没有被删除。

Entonces puedes darte cuenta de que el cuerpo de la serpiente se vuelve más largo después de comer. Esta lógica es agregar las coordenadas de los alimentos al elemento de la cola del vector sin eliminar el elemento de la cabeza, y “只插尾”.

4.4 Las serpientes no pueden moverse en reversa

Es decir, si la dirección de movimiento de la serpiente es correcta y accidentalmente presiono la tecla A (izquierda), la serpiente no puede retroceder.
Se necesita definir una variable oldDirection para registrar la última dirección de movimiento para juzgar con la dirección obtenida actualmente.
inserte la descripción de la imagen aquí

4.5 Refrescarse después de comer

Actualizar es muy simple, solo regenere uno, pero cómo juzgar si se come la comida, puede verificar si las coordenadas actuales de la cabeza de la serpiente son iguales a las coordenadas de la comida, si no, significa que la serpiente no se ha comido
, luego continúe moviendo el cuerpo de la serpiente, si se come, regenere la comida.
inserte la descripción de la imagen aquí
También está aquí para registrar la cantidad de alimentos consumidos Para myCount en la captura de pantalla anterior, si desea obtener una puntuación, puede multiplicarla por un coeficiente de puntuación de alimentos.

4.6 La comida no puede desovar en las serpientes

Aquí necesitas regenerar primero, y luego emitir un juicio.
inserte la descripción de la imagen aquí
Aquí encapsulamos el juicio sobre si la comida se produce en el cuerpo de la serpiente, usando find() en el algoritmo STL:

bool IsFoodEqualSnack(vector<pair<int, int>> vec, pair<int, int> food)
{
    
    
	if (!vec.empty())
	{
    
    
		auto result = find(begin(vec), end(vec), food);
		if ( result != vec.end() )
		{
    
    
			return true;
		}
		else
		{
    
    
			return false;
		}
	}
	else
	{
    
    
		cout << "vector is empty" << endl;
		return false;
	}
	cout << endl;

}

4.7 Configuración de la dificultad del juego

En la actualidad, la velocidad de movimiento está controlada por Sleep (). La lógica es que la longitud de la serpiente actual menos la longitud en el momento de la inicialización, y luego tomar el resto de 2, es decir, cada vez que se comen dos alimentos, la velocidad de movimiento aumenta en una marcha.

void setSpeed(Snack objSnack)
{
    
    
	Sleep( 1000 / speedLevel ); 
	if ( (objSnack.mV.size() - 3 != 0))
	{
    
    
		if ( (oldspeed != (objSnack.mV.size() - 3) % 2) &&
			 ((objSnack.mV.size() - 3) % 2 == 0) )
		{
    
    
			speedLevel++;
		}
	}
	oldspeed = (objSnack.mV.size() - 3) % 2;
}

4.8 Una serpiente no puede golpearse a sí misma

La lógica que necesitamos aquí es que los elementos repetidos no se pueden incluir en el vector del cuerpo de la serpiente.¿Cómo se puede lograr esto?
Es muy simple. Usando la característica única del contenedor del conjunto, asignamos el vector del cuerpo de la serpiente a un contenedor del conjunto y juzgamos si el tamaño del conjunto es el mismo que el del vector del cuerpo de la serpiente. Depende de mí, GameOver .

bool Snack::isHitItself()
{
    
    
    mSet = {
    
     mV.begin(),mV.end() };
    if (mSet.size() != mV.size())//蛇头撞到了蛇身
    {
    
    
        return true;
    }
    else
    {
    
    
        return false;
    }
}

4.8 Las serpientes no pueden chocar contra las paredes

Esto es muy simple, no hay nada que decir.

bool Snack::isHitWall()
{
    
    
    if ( (mV.end()-1)->first == MAP_X *2  ||
         (mV.end() - 1)->first == 0       ||
         (mV.end() - 1)->second == MAP_Y  ||
         (mV.end() - 1)->second == 0)
    {
    
    
        return true;
    }
    else
    {
    
    
        return false;
    }
}

5. Diagrama de flujo

inserte la descripción de la imagen aquí

6. Código

Si el entorno es el adecuado, definitivamente puede funcionar con normalidad. El 99,99 % de los errores se han solucionado durante el proceso de desarrollo y ya no hay errores.
descarga de código

7. Conclusión

¡El contenido de este artículo es completamente original y no se permite su reproducción! ! !

Supongo que te gusta

Origin blog.csdn.net/qq_45458713/article/details/129410974
Recomendado
Clasificación