#简单实现贪吃蛇小游戏
##简介
经过一天的时间,终于简单实现了游戏的大部分,代码可能存在问题,就当练手了吧。
具体代码如下:
/*********************************************************************
* 工程:贪吃蛇
* 文件:main.cpp
* 时间:2017.11.27
* 编译环境:windows 10
* codeblock
* 简要概述:通过键盘上‘w’,‘a’,’s‘,‘d’,控制蛇身移动
* 不足: 1.只有按键蛇身才会动
* 2.代码略显冗长
*********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <windows.h>
#define WIDTH 50
#define HEIGHT 25
enum direction { up, down, right, left }; //方向枚举
enum direction g_direc = right; //全局变量
int array[HEIGHT][WIDTH] = {0, 0}; //界面数组
/*****************************链表相关函数***********************************/
//创建链表结构体
struct node
{
int x;
int y;
struct node *next;
};
struct node *head = NULL;
//链表输出
void out_date(struct node *p)
{
if (p->next == NULL)
{
printf("没有数据\n");
}
else
{
printf("数据为");
while(p->next)
{
p = p->next;
printf("x=%d ", p->x);
printf("y=%d ", p->y);
}
printf("\n");
}
}
//链表增加一位
void insert(struct node *p, int val_x, int val_y)
{
struct node *pt = p;
//新节点
struct node *pn = NULL;
//动态获取长度
pn = (struct node *)malloc(sizeof(struct node));
pn->x = val_x;
pn->y = val_y;
pn->next = NULL;
if (pt->next == NULL)
{
pt->next = pn;
}
else
{
while(pt->next)
{
pt = pt->next;
if (pt->next == NULL)
{
pt->next = pn;
break;
}
}
}
}
/*****************************链表相关函数***********************************/
/****************************************************************************
10 代表围墙
0 代表空
1 代表蛇身
2 代表食物
****************************************************************************/
//更新地图
void update()
{
system("cls");
int ii = 0, jj = 0;
for (ii = 0; ii < HEIGHT; ii++)
{
for (jj = 0; jj < WIDTH; jj++) //遍历每行
{
if (array[ii][jj] == 10)
printf("#");
if (array[ii][jj] == 0)
printf(" ");
if (array[ii][jj] == 1)
printf("*");
if (array[ii][jj] == 2)
printf("@");
}
printf("\n");
}
}
//初始化函数
void init()
{
//打印围墙
int i = 0, j = 0;
for (i = 0; i < HEIGHT; i++)
{
for (j = 0; j < WIDTH; j++) //遍历每行
{
if (i == 0 || i == HEIGHT - 1 || j == 0 || j == WIDTH - 1 )
{
array[i][j] = 10; //10代表围墙
}
else array[i][j] = 0;
}
}
//打印蛇身(位置:正中间)
int k = 0;
for (k = 0; k < 4; k++)
{
array[HEIGHT / 2][WIDTH / 2 - 4 + k] = 1;
}
//打印食物
srand((unsigned)time( NULL ));
int food_x = (rand()%(WIDTH - 1 - 1)) + 1;
int food_y = (rand()%(HEIGHT - 1 - 1)) + 1;
while(array[food_y][food_x] == 1) //避免随机数出现在蛇身
{
printf("sdsafd");
food_x = (rand()%(WIDTH - 1 - 1)) + 1;
food_y = (rand()%(HEIGHT - 1 - 1)) + 1;
}
array[food_y][food_x] = 2;
//链表初始化
head = (struct node *)malloc(sizeof(struct node));
head->x = 0;
head->y = 0;
head->next = NULL;
//添加蛇身数据到链表
insert(head, WIDTH / 2 - 4 + 0, HEIGHT / 2);
insert(head, WIDTH / 2 - 4 + 1, HEIGHT / 2);
insert(head, WIDTH / 2 - 4 + 2, HEIGHT / 2);
insert(head, WIDTH / 2 - 4 + 3, HEIGHT / 2);
//out_date(head);
//初始化显示
update();
}
//移动:向上
void move_up()
{
if (g_direc != down) //上一次运动不能为向下
{
struct node *temp = head;
temp = temp->next; //蛇尾
struct node *p_fin = head;
while(p_fin->next) //蛇头下一个目标
{
p_fin = p_fin->next;
}
if (array[p_fin->y - 1][p_fin->x] == 0) //下一位置为空位
{
array[temp->y][temp->x] = 0; //蛇尾为空(0)
array[p_fin->y - 1][p_fin->x] = 1; //蛇头更新(1)
head = head->next; //链表右移一位
insert(head, p_fin->x, p_fin->y - 1); //链表添加新蛇头
}
else if (array[p_fin->y - 1][p_fin->x] == 2)//下一位置为食物
{
array[p_fin->y - 1][p_fin->x] = 1; //蛇头更新(1)
insert(head, p_fin->x, p_fin->y - 1); //链表添加新蛇头
//更新食物
srand((unsigned)time( NULL ));
int food_x = (rand()%(WIDTH - 1 - 1)) + 1;
int food_y = (rand()%(HEIGHT - 1 - 1)) + 1;
while(array[food_y][food_x] == 1)
{
printf("sdsafd");
food_x = (rand()%(WIDTH - 1 - 1)) + 1;
food_y = (rand()%(HEIGHT - 1 - 1)) + 1;
}
array[food_y][food_x] = 2;
}
else //下一位置为撞墙或撞自身
{
printf("failed\n");
}
g_direc = up; //更新方向
}
}
//移动:向下
void move_down()
{
if (g_direc != up)
{
struct node *temp = head;
temp = temp->next; //蛇尾
struct node *p_fin = head;
while(p_fin->next) //蛇头下一个目标
{
p_fin = p_fin->next;
}
if (array[p_fin->y + 1][p_fin->x] == 0) //空位
{
array[temp->y][temp->x] = 0;
array[p_fin->y + 1][p_fin->x] = 1;
head = head->next;
insert(head, p_fin->x, p_fin->y + 1);
}
else if (array[p_fin->y + 1][p_fin->x] == 2)//食物
{
array[p_fin->y + 1][p_fin->x] = 1;
insert(head, p_fin->x, p_fin->y + 1);
//更新食物
srand((unsigned)time( NULL ));
int food_x = (rand()%(WIDTH - 1 - 1)) + 1;
int food_y = (rand()%(HEIGHT - 1 - 1)) + 1;
while(array[food_y][food_x] == 1)
{
printf("sdsafd");
food_x = (rand()%(WIDTH - 1 - 1)) + 1;
food_y = (rand()%(HEIGHT - 1 - 1)) + 1;
}
array[food_y][food_x] = 2;
}
else //撞墙或撞自身
{
printf("failed\n");
}
g_direc = down;
}
}
//移动:向右
void move_right()
{
if (g_direc != left)
{
struct node *temp = head;
temp = temp->next; //蛇尾
struct node *p_fin = head;
while(p_fin->next) //蛇头下一个目标
{
p_fin = p_fin->next;
}
if (array[p_fin->y][p_fin->x + 1] == 0) //空位
{
array[temp->y][temp->x] = 0;
array[p_fin->y][p_fin->x + 1] = 1;
head = head->next;
insert(head, p_fin->x + 1, p_fin->y);
}
else if (array[p_fin->y][p_fin->x + 1] == 2)//食物
{
array[p_fin->y][p_fin->x + 1] = 1;
insert(head, p_fin->x + 1, p_fin->y);
//更新食物
srand((unsigned)time( NULL ));
int food_x = (rand()%(WIDTH - 1 - 1)) + 1;
int food_y = (rand()%(HEIGHT - 1 - 1)) + 1;
while(array[food_y][food_x] == 1)
{
printf("sdsafd");
food_x = (rand()%(WIDTH - 1 - 1)) + 1;
food_y = (rand()%(HEIGHT - 1 - 1)) + 1;
}
array[food_y][food_x] = 2;
}
else //撞墙或撞自身
{
printf("failed\n");
}
g_direc = right;
}
}
//移动:向左
void move_left()
{
if (g_direc != right)
{
struct node *temp = head;
temp = temp->next; //蛇尾
struct node *p_fin = head;
while(p_fin->next) //蛇头下一个目标
{
p_fin = p_fin->next;
}
if (array[p_fin->y][p_fin->x - 1] == 0) //空位
{
array[temp->y][temp->x] = 0;
array[p_fin->y][p_fin->x - 1] = 1;
head = head->next;
insert(head, p_fin->x - 1, p_fin->y);
}
else if (array[p_fin->y][p_fin->x - 1] == 2)//食物
{
array[p_fin->y][p_fin->x - 1] = 1;
insert(head, p_fin->x - 1, p_fin->y);
//更新食物
srand((unsigned)time( NULL ));
int food_x = (rand()%(WIDTH - 1 - 1)) + 1;
int food_y = (rand()%(HEIGHT - 1 - 1)) + 1;
while(array[food_y][food_x] == 1)
{
printf("sdsafd");
food_x = (rand()%(WIDTH - 1 - 1)) + 1;
food_y = (rand()%(HEIGHT - 1 - 1)) + 1;
}
array[food_y][food_x] = 2;
}
else //撞墙或撞自身
{
printf("failed\n");
}
g_direc = left;
}
}
//交互操作
void get_key()
{
char key = 0;
while(1)
{
key = getch(); //获取键值(无需回车即可输入)
switch(key)
{
case 'w': move_up(); update();break;
case 'a': move_left(); update();break;
case 's': move_down(); update();break;
case 'd': move_right(); update();break;
}
}
}
int main()
{
init(); //初始化
get_key(); //获取按键值
return 0;
}