C语言敲贪吃蛇的框架,简单贪吃蛇C语言版高级版(一):基本框架搭建

以前的一篇文章用C写的控制台版简易贪吃蛇中讲述了一个非常不规范的贪吃蛇,整个程序内部的变量等等非常的散乱,是在老师给的程序上改变成的,后来在看了大神写的贪吃蛇贪吃蛇 AI 的实现 snake AI之后我便萌生了自己再重新写一个贪吃蛇程序的念头,这个程序在不断的搭建中,这篇文章主要介绍基本框架的搭建,包括贪吃蛇的界面,行走函数,显示函数等等。

因为尽量使用C语言,所以没有使用类,使用的是结构体来定义基本的“类”。到目前为止,基本的框架中包含三个重要的结构体,点,地图,蛇。首先看“点:结构体。

点:基本代码如下

struct Point

{

int x;

int y;

char symbol;

bool isSafe;

void setPoint(int InputX, int InputY)

{

x = InputX;

y = InputY;

}

};

定义了x,y代表对应在地图上的坐标,symbol表示该点显示的符号,isSafe表示该点是否安全(是否被占据):true表示安全,false表示不安全。setPoint()函数用来设置xy值。

地图:基本代码如下

struct Map

{

Point map[20][20];

Point indexMap[20][20];

void show()

{

system("cls");

for(int i = 0; i <= 19; i++)

{

for(int j = 0; j <= 19; j++)

{

printf("%c",map[i][j].symbol);

}

printf("\n");

}

}

};

map[20][20]是由20×20个点组成的地图,indexMap和map就大小而言是一样的,但是上面储存的xy代表的是map中对应的上一个坐标,在寻路算法中有一种Breadth算法,需要知道当前点对应的上一个点在哪,所以开辟了一个indexMap用来记录真实地图中的对应关系。show()函数用来显示地图。地图中的坐标轴如下图示意

0818b9ca8b590ca3270a3433284dd417.png

蛇:基本代码如下

struct Snake

{

Point head;

vector body;

Point temp;

void initSnake(Map* map)

{

head.x = 0;

head.y = 3;

for(int i = 2; i >= 0; i--)

{

temp.setPoint(0,i);

temp.symbol = '*';

temp.isSafe = false;

body.push_back(temp);

map->map[body[2-i].x][body[2-i].y].symbol = '*';

map->map[body[2-i].x][body[2-i].y].isSafe = false;

}

map->map[head.x][head.y].symbol = '#';

map->map[head.x][head.y].isSafe = false;

}

void MoveUp(Map* map)

{

map->map[head.x][head.y].symbol = '*';

//body[0] = head;

head.x--;

map->map[body.back().x][body.back().y].symbol = ' ';

map->map[body.back().x][body.back().y].isSafe = true;

/*body.back().symbol = body[body.size()-1].symbol;

body.back().setPoint(body[body.size()-1].x,body[body.size()-1].y);*/

//body.back().setPoint(body[body.size()-2].x,body[body.size()-2].y);

for(int i = 2; i >= 1; i--)

{

body[i] = body[i-1];

}

body[0].setPoint(head.x+1,head.y);

map->map[head.x][head.y].symbol = '#';

map->map[head.x][head.y].isSafe = false;

}

void MoveDown(Map* map)

{

map->map[head.x][head.y].symbol = '*';

//body[0] = head;

head.x++;

map->map[body.back().x][body.back().y].symbol = ' ';

map->map[body.back().x][body.back().y].isSafe = true;

/*body.back().symbol = body[body.size()-1].symbol;

body.back().setPoint(body[body.size()-1].x,body[body.size()-1].y);*/

//body.back().setPoint(body[body.size()-2].x,body[body.size()-2].y);

for(int i = 2; i >= 1; i--)

{

body[i] = body[i-1];

}

body[0].setPoint(head.x-1,head.y);

map->map[head.x][head.y].symbol = '#';

map->map[head.x][head.y].isSafe = false;

}

void MoveLeft(Map* map)

{

map->map[head.x][head.y].symbol = '*';

//body[0] = head;

head.y--;

map->map[body.back().x][body.back().y].symbol = ' ';

map->map[body.back().x][body.back().y].isSafe = true;

/*body.back().symbol = body[body.size()-1].symbol;

body.back().setPoint(body[body.size()-1].x,body[body.size()-1].y);*/

//body.back().setPoint(body[body.size()-2].x,body[body.size()-2].y);

for(int i = 2; i >= 1; i--)

{

body[i] = body[i-1];

}

body[0].setPoint(head.x,head.y+1);

map->map[head.x][head.y].symbol = '#';

map->map[head.x][head.y].isSafe = false;

}

void MoveRight(Map* map)

{

map->map[head.x][head.y].symbol = '*';

//body[0] = head;

head.y++;

map->map[body.back().x][body.back().y].symbol = ' ';

map->map[body.back().x][body.back().y].isSafe = true;

//body.pop_back();

//body.back().setPoint(body[body.size()-2].x,body[body.size()-2].y);

for(int i = 2; i >= 1; i--)

{

body[i] = body[i-1];

}

body[0].setPoint(head.x,head.y-1);

map->map[head.x][head.y].symbol = '#';

map->map[head.x][head.y].isSafe = false;

}

};

一个类别一个类别的看,

Point head;

vector body;

Point temp;

void initSnake(Map* map)

{

head.x = 0;

head.y = 3;

for(int i = 2; i >= 0; i--)

{

temp.setPoint(0,i);

temp.symbol = '*';

temp.isSafe = false;

body.push_back(temp);

map->map[body[2-i].x][body[2-i].y].symbol = '*';

map->map[body[2-i].x][body[2-i].y].isSafe = false;

}

map->map[head.x][head.y].symbol = '#';

map->map[head.x][head.y].isSafe = false;

}

在这段代码里面定义了蛇的头和身体,身体使用vector来记录,在后期加上吃果子会变长的特性后需要加长蛇身,用vector可以方便的管理。定义一个临时点temp,在initSnake(Map* map)函数中方便赋值,initSnake(Map* map)函数用来初始化蛇的位置,坐标,显示字符等,传入的参数是地图的地址。然后就是四个基本的移动函数:

void MoveUp(Map* map)

void MoveDown(Map* map)

void MoveRight(Map* map)

void MoveLeft(Map* map)

具体的移动方法请自行查看。基本框架搭建完毕,在主函数中实验一下,代码如下

int main()

{

Map map;

Snake snake;

for(int i = 0; i <= 19; i++)

{

for(int j = 0; j <= 19; j++)

{

map.map[i][j].setPoint(i,j);

map.map[i][j].symbol = ' ';

map.map[i][j].isSafe = true;

map.indexMap[i][j].setPoint(i,j);

map.indexMap[i][j].symbol = ' ';

map.indexMap[i][j].isSafe = true;

}

}

snake.initSnake(&map);

snake.MoveRight(&map);

snake.MoveDown(&map);

snake.MoveLeft(&map);

snake.MoveUp(&map);

map.show();

}

显示结果如下

0818b9ca8b590ca3270a3433284dd417.png

另外增加一个产生果实的函数Seed(Map* map),代码如下

void Seed(Map* map)

{

srand((unsigned)time(NULL));

int x = rand()%19;

int y = rand()%19;

if(map->map[x][y].isSafe)

{

map->map[x][y].isSafe = false;

map->map[x][y].symbol = '&';

map->map[x][y].setPoint(x,y);

}

}

因为使用了随机数,所以需要包含#include 以及#include ,在主函数调用Seed(&map)就可以放置果实

0818b9ca8b590ca3270a3433284dd417.png

整个贪吃蛇的基本框架已经搭建好,还剩下吃了果实会变长的功能以及智能寻路算法。会另外开文章。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值