Recientemente , estoy obsesionado con escribir juegos, aunque todos son versiones simples de DOS (falló el intento anterior de programación visual), tic-tac-toe , gomoku y laberintos en movimiento , se me ocurrió una serpiente que no ha sido diseñada. Entonces se diseñó el siguiente programa.
programa
// This is a simple snake game.
#include <iostream>
#include <string>
#include <vector>
#include <cstddef>
#include <Windows.h>
#include <conio.h>
#include <random>
#include <ctime>
#include <deque>
using namespace std;
struct location {
unsigned x, y;
}loc1, loc2;
int state = 0;
int ret = 4; // head right by default
unsigned cnt = 0;
unsigned score = 0;
char p[25][30]; // the board
vector<location> vec;
deque<location> snake;
void p_def() // define p
{
for (int i = 0; i != 25; i++)
{
if (i != 0 && i != 24)
{
p[i][0] = p[i][29] = '*';
for (int j = 1; j != 29; j++)
p[i][j] = ' ';
}
else
{
for (int j = 0; j != 30; j++)
p[i][j] = '*';
}
}
p[13][5] = 'O'; // body
p[13][6] = '@'; // head
loc1.x = 13;
loc1.y = 6; // the initial location of the head of the snake
loc2.x = 13;
loc2.y = 5; // the initial location of the tail of the snake
snake.push_front(loc2); // store the first location of the snake tail
}
void input(char c1, char c2)
{
c1 = _getch();
c2 = _getch();
switch (c2)
{
case 72: // up
if (ret != 2)
ret = 1;
break;
case 80: // down
if (ret != 1)
ret = 2;
break;
case 75: // left
if (ret != 4)
ret = 3;
break;
case 77: // right
if (ret != 3)
ret = 4;
break;
default:
break;
}
}
void print()
{
for (int i = 0; i != 25; i++)
{
for (int j = 0; j != 30; j++)
std::cout << " " << p[i][j];
std::cout << endl;
}
}
void ran() // generate a random food for the snake to eat
{
default_random_engine random1, random2;
for (int i = 0; i != 644; i++)
{
unsigned ran1 = random1() % 23 + 1; // ranging from 1 to 23
unsigned ran2 = random2() % 28 + 1; // ranging from 1 to 28
location ran_l;
ran_l.x = ran1;
ran_l.y = ran2;
vec.push_back(ran_l);
}
}
void move()
{
switch (ret)
{
case 1: // up
if (p[loc1.x - 1][loc1.y] == 'O' || p[loc1.x - 1][loc1.y] == '*')
state = 1; // indicate the end of the game
else
{
if (p[loc1.x - 1][loc1.y] == '#')
{
score++;
snake.push_front(loc1);
}
else
{
p[snake.back().x][snake.back().y] = ' '; // delete the end of the tail
snake.pop_back();
snake.push_front(loc1); // former head -> front of the tail
}
}
--loc1.x;
break;
case 2: // down
if (p[loc1.x + 1][loc1.y] == 'O' || p[loc1.x + 1][loc1.y] == '*')
state = 1; // indicate the end of the game
else
{
if (p[loc1.x + 1][loc1.y] == '#')
{
score++;
snake.push_front(loc1);
}
else
{
p[snake.back().x][snake.back().y] = ' '; // delete the end of the tail
snake.pop_back();
snake.push_front(loc1); // former head -> front of the tail
}
}
++loc1.x;
break;
case 3: // left
if (p[loc1.x][loc1.y - 1] == 'O' || p[loc1.x][loc1.y - 1] == '*')
state = 1; // indicate the end of the game
else
{
if (p[loc1.x][loc1.y - 1] == '#')
{
score++;
snake.push_front(loc1);
}
else
{
p[snake.back().x][snake.back().y] = ' '; // delete the end of the tail
snake.pop_back();
snake.push_front(loc1); // former head -> front of the tail
}
}
--loc1.y;
break;
case 4: // right
if (p[loc1.x][loc1.y + 1] == 'O' || p[loc1.x][loc1.y + 1] == '*')
state = 1; // indicate the end of the game
else
{
if (p[loc1.x][loc1.y + 1] == '#')
{
score++;
snake.push_front(loc1);
}
else
{
p[snake.back().x][snake.back().y] = ' '; // delete the end of the tail
snake.pop_back();
snake.push_front(loc1); // former head -> front of the tail
}
}
++loc1.y;
break;
default: //others
break;
}
for (auto c : snake)
p[c.x][c.y] = 'O'; // print the tail
p[loc1.x][loc1.y] = '@'; // print the head
}
int main()
{
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cci;
GetConsoleCursorInfo(hOut, &cci);
cci.bVisible = FALSE;
SetConsoleCursorInfo(hOut, &cci);
// The five lines above are used to hide the Console Cursor.
char c1 = '\0', c2 = '\0';
int time_set;
std::cout << "This is a simple snake game.\nProgrammer:Teddy van Jerry" << endl;
Sleep(300);
std::cout << "\nNow Loading";
for (int i = 0; i != 6; i++)
{
Sleep(200);
std::cout << ".";
}
Sleep(500); // stop for a while
std::cout << "\n\nYou can move the snake using ↑,↓,←,→." << endl;
std::cout << "\nYou can choose the speed the snake moves.\nVery slow(1) Slow(2) Medium(3) Fast(4) Very Fast(5) Very Very Fast(6)" << endl;
char choice;
choice = _getch();
switch (choice) // set the speed
{
case '1':
time_set = 1000;
break;
case '2':
time_set = 700;
break;
case '3':
time_set = 500;
break;
case '4':
time_set = 350;
break;
case '5':
time_set = 250;
break;
case '6':
time_set = 150;
break;
default:
time_set = 500;
break;
}
p_def(); // define p
cout << "\nNow get ready!\n" << endl;
Sleep(3500);
ran();
while (state == 0)
{
unsigned long clock_p = clock();
print();
std::cout << "\nYour current score is " << score << " .\n" << endl;
do
{
if (_kbhit()) // test if there is a click on the button
input(c1, c2);
} while (clock() - clock_p < time_set);
move();
if (p[(vec[cnt]).x][(vec[cnt]).y] == ' ')
p[(vec[cnt]).x][(vec[cnt]).y] = '#'; // generate food for the snake to eat
cnt++;
}
std::cout << "\nThe game is over.\nYour final score is " << score << " !" << endl;
std::cout << "\nALL RIGHTS RESERVED (c) 2020 Teddy van Jerry" << endl;
char anything;
cin >> anything;
return 0;
}
// ALL RIGHTS RESERVED (c) 2020 Teddy van Jerry
Salida de muestra
(Algunas deficiencias son que el programa parpadeará un poco, esto no es posible)
análisis
- Escribí muchas preguntas al principio y me llevó mucho tiempo encontrar errores.
Luego sucedió de nuevo (¿Por qué se cortó toda la cabeza y el cuerpo?) Y
luego sucedió nuevamente (se ve bien, pero en realidad no se puede mover)
- Puede ver la función del tiempo de tratamiento, está en la biblioteca
ctime
de latime()
función, en milisegundos, la salida real es larga. Sleep()
Es la bibliotecaWindows.h
donde se suspende la función tantos milisegundos.- El comportamiento 192-196 cancela el código del cursor, que se encuentra en línea.
- La
_kbhit()
entrada de la línea 248 determina si la entrada del teclado o no. Aquí el uso_getch()
no sirve de nada (estas dos funciones en la biblioteca estánconio.h
adentro), probé esta antes de tantas razones equivocadas. Resulta que el programa se atascará en la entrada sin juzgar, y no se moverá si no lo ingresa. - Con respecto a la entrada de las teclas de flecha, consulte mi blog [Programa C ++] Aplicación y análisis en Mobile Maze Game .
- El almacenamiento de la cola de serpiente está en el interior.La
deque
ventaja es que los dos extremos son operables y la salida es conveniente. El uso específico se puede buscar en CSDN. - El script 258-259 no tiene sentido, el propósito es usar el archivo exe solo, a veces cuando el juego termina, se cierra directamente sin mostrar el resultado final. Agrega esta oración inútil para resolverlo. Vea mi blog pensando en el programa C ++ que se ejecuta en otros dispositivos .
- Para la función de posición aleatoria personalizada,
ran()
consulte mi blog [Programa C ++] Número aleatorio . - Vea las funciones definidas por mi blog sobre el impacto de las definiciones de funciones de Pensamiento en C ++ .
TODOS LOS DERECHOS RESERVADOS © 2020 Teddy van Jerry
bienvenido a reimprimir, por favor indique la fuente.
Ver también
Página de navegación de Teddy van Jerry
[Programa C ++] Juego Gobang (humano VS humano)
[Programa C ++] Juego Tic-Tac-Toe (humano VS humano)
[Programa C ++] Juego Tic-Tac-Toe (humano VS computadora Lv1)
[Programa C ++] Tic Tac-Toe Juego de ajedrez (Computadora humana VS Lv2)
[Programa C ++] Juego Tic-Tac-Toe (Computadora humana VS Lv3)
[Programa C ++] Juego Tic-Tac-Toe (Computadora humana VS Lv3) (Versión estadística)
[Programa C ++] Juego de laberinto en movimiento
[C ++ Programa] Número aleatorio
[Programa C ++] Juego de tablero digital push (15 rompecabezas)
[Programa C ++] Juego 2048
[ Programa C ++] Juego Tic-Tac-Toe (humano VS humano) (Interfaz gráfica EasyX)
[Programa C ++] Juego Tic-Tac-Toe ( Human VS Lv3 Computer) (Record Statistics Edition) (Interfaz gráfica EasyX)