控制台版贪吃蛇

来源:互联网 发布:孤单北半球 知乎 编辑:程序博客网 时间:2024/04/28 23:34
#include<cstdio>
#include<windows.h>
#include<time.h>
#include<cstdlib>
#include<assert.h>
//地图大小
#define MAP_SIZE 20
//全局屏幕输出缓存区句柄
HANDLE g_hOutput;
//地图属性
struct MapNode_s
{
enum NodeType_e{NOTHING, SNAKE , WALL, FOOD};
NodeType_e type;
};
//全局地图数据
MapNode_s g_map[MAP_SIZE][MAP_SIZE];
//蛇属性
struct Snake_s
{
//上 下 左 右
enum Dir_e{UP, DOWN, LEFT, RIGHT};
struct SnakeNode
{
short x;
short y;
SnakeNode * next;
SnakeNode * last;
};
Dir_e dir;
SnakeNode  * head;
SnakeNode  * tail;
bool isDie;
int eat;
};
//全局蛇变量
Snake_s g_snake;
//蛇移动
void Move();
//清空蛇
void DeleteSnake();
//蛇移动
void Move();
//全局初始化
void AllInit();
//全局卸载
void AllUnInit();
//设置光标位置函数
void Pos(SHORT x, SHORT y);
//地图初始化
void InitMap();
//打印地图
void PrintAll();
//游戏循环
void GameLoop();
//刷新一个食物
void RandPushFood();


int main()
{
AllInit();
GameLoop();
AllUnInit();
getchar();
return 0;
}


void AllInit()
{
g_hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
g_snake.dir = Snake_s::RIGHT;
g_snake.tail = g_snake.head = new Snake_s::SnakeNode;
g_snake.head->x = 1;
g_snake.head->y = 1;
g_snake.head->next = 0;
g_snake.head->last = 0;
g_snake.eat = 0;
g_snake.isDie = false;
InitMap();
}


void AllUnInit()
{
DeleteSnake();
}


void Pos(SHORT x, SHORT y)
{
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(g_hOutput, pos);
return;
}


void InitMap()
{
int i;
for( i = 0; i < MAP_SIZE ; ++i)
{
g_map[0][i].type = MapNode_s::WALL;
g_map[i][0].type = MapNode_s::WALL;
g_map[i][MAP_SIZE - 1].type = MapNode_s::WALL;
g_map[MAP_SIZE - 1][i].type = MapNode_s::WALL;
}
RandPushFood();
}


void PrintAll()
{
Pos(0, 0);
int i,j;
for( i = 0; i < MAP_SIZE ; ++i)
{
for(j = 0; j < MAP_SIZE ; ++j)
{
if(g_map[i][j].type == MapNode_s::WALL)
{
std::printf("■");
}
else if(g_map[i][j].type == MapNode_s::FOOD)
{
std::printf("★");
}
else if(g_map[i][j].type == MapNode_s::SNAKE)
{
std::printf("※");
}
else if(g_map[i][j].type == MapNode_s::NOTHING)
{
std::printf("  ");
}
}
std::printf("\n");
}
Pos(0, MAP_SIZE);
std::printf("吃了:%d\n", g_snake.eat);
}


void GameLoop()
{
while(true)
{
//判断用户的按键输入
if(GetAsyncKeyState(VK_UP) && g_snake.dir != Snake_s::DOWN)
g_snake.dir = Snake_s::UP;
else if(GetAsyncKeyState(VK_DOWN) && g_snake.dir != Snake_s::UP)
g_snake.dir = Snake_s::DOWN;
else if(GetAsyncKeyState(VK_LEFT) && g_snake.dir != Snake_s::RIGHT)
g_snake.dir = Snake_s::LEFT;
else if(GetAsyncKeyState(VK_RIGHT) && g_snake.dir != Snake_s::LEFT)
g_snake.dir = Snake_s::RIGHT;


Move();
if(g_snake.isDie)
{
return;
}
Sleep(500);
PrintAll();
}
}


void DeleteSnake()
{
Snake_s::SnakeNode * node = g_snake.head;
if(!node)
return;
Snake_s::SnakeNode * it;
while(node)
{
it = node->next;
delete node;
node = it;
}
}


void Move()
{
Snake_s::SnakeNode it;
it = *g_snake.head;
switch(g_snake.dir)
{
case Snake_s::UP:
it.y -= 1;
break;
case Snake_s::DOWN:
it.y += 1;
break;
case Snake_s::LEFT:
it.x -= 1;
break;
case Snake_s::RIGHT:
it.x += 1;
break;
}
//判断死亡
if(it.y < 0 || it.y >= MAP_SIZE || it.x < 0 || it.x >= MAP_SIZE || g_map[it.y][it.x].type == MapNode_s::WALL || g_map[it.y][it.x].type == MapNode_s::SNAKE)
{
g_snake.isDie = true; 
}
//判断是否是食物
else if(g_map[it.y][it.x].type == MapNode_s::FOOD)
{
g_map[it.y][it.x].type = MapNode_s::SNAKE;
Snake_s::SnakeNode * newhead = new Snake_s::SnakeNode;
newhead->x = it.x;
newhead->y = it.y;
newhead->last = 0;
newhead->next = g_snake.head;
g_snake.head->last = newhead;
g_snake.head = newhead;
++g_snake.eat;
RandPushFood();
}
//普通移动
else
{
Snake_s::SnakeNode * it2;
it2 = g_snake.head;
while(it2)
{
g_map[it2->y][it2->x].type = MapNode_s::NOTHING;
it2 = it2->next;
}
it2 = g_snake.tail;
while(true)
{
if(it2->last)
{
it2->x = it2->last->x;
it2->y = it2->last->y;
g_map[it2->y][it2->x].type = MapNode_s::SNAKE;
}
else
{
break;
}
it2 = it2->last;
}
g_map[it.y][it.x].type = MapNode_s::SNAKE;
g_snake.head->x = it.x;
g_snake.head->y = it.y;
}
}


void RandPushFood()
{
int j,i;
struct RandNode_s
{
int x;
int y;
};
RandNode_s p[MAP_SIZE * MAP_SIZE];
int z = 0;
for(i = 0; i < MAP_SIZE ; ++i)
for(j = 0; j < MAP_SIZE ; ++j)
if(g_map[i][j].type == MapNode_s::NOTHING)
{
p[z].x = i;
p[z].y = j;
++z;
}

if(z == 0)
assert(!"QNMLGB");
else
{
int ss = rand() % z;
g_map[p[ss].x][p[ss].y].type = MapNode_s::FOOD;
}
}
原创粉丝点击