代码
#include<iostream>
#include<Windows.h>
#include<conio.h>
#define Wide 60
#define High 27
struct Position//第三步给蛇一个位置
{
int x, y;
};
struct Snack//第3.1步给蛇一些属性
{
Position PositionOfSnack[High * Wide];
int DirectionOfSnack ;
int LengthOfSnack ;
int LastMovetime=0;
int MoveFrequency=200;
};
void InitSnack(Snack* snack)//第3.2步初始化蛇d的属性
{
snack->DirectionOfSnack = 1;
snack->LengthOfSnack = 3;
snack->PositionOfSnack[0] = { Wide / 2, High / 2 };
snack->PositionOfSnack[1] = { Wide / 2-1, High / 2 };
snack->PositionOfSnack[2] = { Wide / 2-2, High / 2 };
}
enum Square//第二步无脑绘制格子
{
NoFood=0,YesFood=1
};
struct MapWithSquare//第2.1步做一个有格子的地图
{
Square s[High][Wide];
int NoOrYes;
};
void hideCursor() {
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cursorInfo;
GetConsoleCursorInfo(hConsole, &cursorInfo);
cursorInfo.bVisible = FALSE; // 隐藏光标
SetConsoleCursorInfo(hConsole, &cursorInfo);
}
void InitMap(MapWithSquare* map)//第2.2步无脑把说有格子都初始化为0
{
for (int y = 0; y < High; ++y)
{
for (int x = 0; x < Wide; ++x)
{
map->s[y][x] = Square::NoFood;
}
}
map->NoOrYes =0;
}
void DrawMap(MapWithSquare* map)//第一步无脑绘制地图
{
std::cout << "◜";
for (int x = 0; x < Wide; x++)//这是上宽的打印
{
std::cout << "-";
}
std::cout << "◝"<<std::endl;
for (int y = 0; y < High; y++)
{
std::cout << "|";
for (int x = 0; x < Wide; x++)
{
if(map->s[y][x]==Square::NoFood)
std::cout << " ";
}
std::cout << "|"<<std::endl;
}
std::cout << "◟";
for (int x = 0; x < Wide; x++)//这是下宽的打印
{
std::cout << "-";
}
std::cout << "◞"<<std::endl;;
}
// 第四步在指定位置上画蛇
void printAtPosition(const std::string& str, Position p) {//蛇
COORD coord;
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
coord.X = p.x + 1;
coord.Y = p.y + 1;
SetConsoleCursorPosition(hOutput, coord);
std::cout << str;
}
void DrawSnack(Snack* snack)
{
for (int i = 0; i < snack->LengthOfSnack; ++i)
{
printAtPosition("777", snack->PositionOfSnack[i]);
}
}
/*我一点也不想写在这个位置(第七步边界检测)*/
bool Bound( Position p)
{
return (p.x == 0 || p.x == Wide + 1 || p.y == 0 || p.y == High + 1);
}
//第五步让蛇动
const int Direction[4][2] = { {-1,0},{0,1},{1,0},{0,-1} };
void MoveSnack(Snack* snack)
{
for (int i = snack->LengthOfSnack - 1; i >= 1; i--)
{
snack->PositionOfSnack[i] = snack->PositionOfSnack[i - 1];
}
snack->PositionOfSnack[0].y+= Direction[snack->DirectionOfSnack][0];
snack->PositionOfSnack[0].x+= Direction[snack->DirectionOfSnack][1];
}
bool doMove(Snack* snack, MapWithSquare* map)
{
Position tail = snack->PositionOfSnack[snack->LengthOfSnack - 1];
printAtPosition(" ", tail);
MoveSnack(snack);
if (Bound(snack->PositionOfSnack[0]))
{
return false;
}
printAtPosition("7",snack->PositionOfSnack[0]);
return true;
}
bool CheckSnackMove(Snack* snack, MapWithSquare* map)
{
//第六步频率控制需要@Snack的属性
int curTime = GetTickCount();
if (curTime - snack->LastMovetime > snack->MoveFrequency)
{
if(false== doMove(snack, map))
return false;
snack->LastMovetime = curTime;
}
return true;
}
void UserInteraction(Snack* snack)
{
if (_kbhit())
{
switch (_getch()) {
case'w':
if (snack->DirectionOfSnack != 2)
snack->DirectionOfSnack = 0;
break;
case'a':
if (snack->DirectionOfSnack != 1)
snack->DirectionOfSnack = 3;
break;
case's':
if (snack->DirectionOfSnack != 0)
snack->DirectionOfSnack = 2;
break;
case'd':
if (snack->DirectionOfSnack != 3)
snack->DirectionOfSnack = 1;
break;
default:
break;
}
}
}
//生成食物
#include <cstdlib> // 用于 rand()
#include <ctime> // 用于 time()
struct Food // 第10.1步,添加食物结构体
{
Position pos;
};
void InitFood(Food* food, MapWithSquare* map, Snack* snack) // 第10.2步,初始化食物
{
srand(time(0)); // 设置随机种子
bool validPosition = false;
while (!validPosition)
{
food->pos.x = rand() % Wide;
food->pos.y = rand() % High;
validPosition = map->s[food->pos.y][food->pos.x] == Square::NoFood;
for (int i = 0; i < snack->LengthOfSnack; ++i)
{
if (snack->PositionOfSnack[i].x == food->pos.x && snack->PositionOfSnack[i].y == food->pos.y)
{
validPosition = false;
break;
}
}
}
map->s[food->pos.y][food->pos.x] = Square::YesFood;
}
void DrawFood(Food* food) // 第10.3步,绘制食物
{
printAtPosition("*", food->pos);
}
bool CheckFoodCollision(Snack* snack, Food* food) // 第10.4步,检查食物碰撞
{
return snack->PositionOfSnack[0].x == food->pos.x && snack->PositionOfSnack[0].y == food->pos.y;
}
void HandleFoodCollision(Snack* snack, Food* food, MapWithSquare* map) // 第10.5步,处理食物碰撞
{
if (CheckFoodCollision(snack, food))
{
snack->LengthOfSnack++;
InitFood(food, map, snack); // 重新生成食物
}
}
int main() {
hideCursor();
MapWithSquare map;
Snack snack;
Food food;
InitMap(&map);
InitSnack(&snack);
InitFood(&food, &map, &snack); // 初始化食物
DrawMap(&map);//调用函数画图
DrawSnack(&snack);//调用函数画蛇
DrawFood(&food);
while (1)
{
UserInteraction(&snack);
if (false == CheckSnackMove(&snack, &map))
break;
HandleFoodCollision(&snack, &food, &map); // 10.1处理食物碰撞
}
//第八步游戏结束
printAtPosition("Game Over", { Wide / 2-4,High / 2 });
while (1)
{
}
std::cin.get();
}