#include "GreedySnake.h"
#include"cocos2d.h"
#include "GameScene.h"
USING_NS_CC;
Snake * Snake::createWithSnake(cocos2d::Node * parent)
{
auto snk = new Snake(parent);
return snk;
}
bool Snake::Move(float dt)
{
if (Get_p_ElemOnKey(this->snakeHead, Key) > 0)//撞到自己
{
return false;
}
else if (Get_p_ElemOnKey(this->snakeHead, Key) == -2)//撞墙
{
return false;
}
else if (Get_p_ElemOnKey(this->snakeHead, Key) == -1)//吃到苹果
{
length++;
Seed(&seed);
this->AddHeadElem(&this->snakeHead, &this->snakeHeadLink, Key);
this->Printf(0, snakeTailLink, snakeHeadLink);
}
else//啥都没吃到
{
this->RemoveTailElem(&this->snakeTail, &this->snakeTailLink);
this->AddHeadElem(&this->snakeHead, &this->snakeHeadLink, Key);
this->Printf(1, snakeTailLink, snakeHeadLink);
}
}
Snake::Snake(cocos2d::Node* Pnt)
{
memset(this->Game, 0, sizeof(this->Game));
this->Key = 4;
this->length = 3;
Parent = Pnt;
{
snakeTail.first = 1, snakeTail.second = 15;
snakeTailLink = &Game[1][15];
this->Game[1][15].value = 1;
this->Game[1][15].link = &Game[2][15];
this->Game[2][15].value = 2;
this->Game[2][15].link = &Game[3][15];
this->Game[3][15].value = 3;
snakeHead.first = 3, snakeHead.second = 15;
snakeHeadLink = &this->Game[3][15];
Seed(&seed);
Printf(0, snakeTailLink, snakeHeadLink);
}
}
void Snake::Printf(int i, Node* snakeTail, Node* snakeHead)
{
Parent->removeAllChildren();
/*int pos_x = 0, pos_y = 0;
auto fd = Sprite::create("fd.png");
fd->setTag(2);
fd->setAnchorPoint(Point::ZERO);
fd->setPosition(Point(seed.first * 10,seed.second * 10 ));
Parent->addChild(fd);
while (snakeTail->link != NULL)
{
PosToNext(&pos_x, &pos_y, snakeTail);
auto fd = Sprite::create("ss.png");
fd->setTag(2);
fd->setAnchorPoint(Point::ZERO);
fd->setPosition(Point( pos_x * 10,pos_y * 10));
Parent->addChild(fd);
snakeTail = snakeTail->link;
}
PosToNext(&pos_x, &pos_y, snakeHead);
auto fe = Sprite::create("sh.png");
fe->setTag(2);
fe->setAnchorPoint(Point::ZERO);
fe->setPosition(Point( pos_x * 10,pos_y * 10 ));
Parent->addChild(fe);*/
{
for (int x = 0; x < RANGE_X; x++)
for (int y = 0; y < RANGE_Y; y++)
{
Sprite *a;
if (this->Game[x][y].value > 0)
{
a = Sprite::create("ss.png");
}
else if (this->Game[x][y].value == -1)
a = Sprite::create("fd.png");
else if (this->Game[x][y].value == -2)
continue;
else
a = Sprite::create("ss1.png");
a->setTag(2);
a->setAnchorPoint(Point::ZERO);
a->setPosition(Point(x * 10, y * 10));
Parent->addChild(a);
}
auto b = Sprite::create("sh.png");
b->setTag(2);
b->setZOrder(2);
b->setAnchorPoint(Point::ZERO);
b->setPosition(Point(this->snakeHead.first * 10, this->snakeHead.second * 10));
Parent->addChild(b);
{
CCString* ns = CCString::createWithFormat("Score: %d", this->length);
const char *str = ns->getCString();
auto ss = Label::createWithTTF(str, "fonts/Marker Felt.ttf", 20);
ss->setPosition(Point(400, 300));
Parent->addChild(ss);
}
}
}
void Snake::Pos(int * pos_x, int * pos_y, const pair<int, int> intElem)
{
if (intElem.first >= RANGE_X - 1)
*pos_x = 1;
else if (intElem.first <= 0)
*pos_x = -1;
else
*pos_x = 0;
if (intElem.second >= RANGE_Y - 1)
*pos_y = 1;
else if (intElem.second <= 0)
*pos_y = -1;
else
*pos_y = 0;
}
int Snake::Get_p_ElemOnKey(const pair<int, int> intHead, const int Key)
{
int Pos_x, Pos_y;
Pos(&Pos_x, &Pos_y, intHead);
if (Pos_x == -1 && Key == 3)
return this->Game[RANGE_X - 1][intHead.second].value;
else if (Pos_x == 1 && Key == 4)
return this->Game[0][intHead.second].value;
else if (Pos_y == -1 && Key == 2)
return this->Game[intHead.first][RANGE_Y - 1].value;
else if (Pos_y == 1 && Key == 1)
return this->Game[intHead.first][0].value;
else
{
switch (Key)
{
case 3:return this->Game[intHead.first - 1][intHead.second].value;
case 4:return this->Game[intHead.first + 1][intHead.second].value;
case 2:return this->Game[intHead.first][intHead.second - 1].value;
case 1:return this->Game[intHead.first][intHead.second + 1].value;
default:
break;
}
}
}
void Snake::Seed(pair<int, int> *seed)
{
srand((unsigned)time(NULL));
int x = rand() % RANGE_X, y = rand() % RANGE_Y;
while (Game[x][y].value != 0)
{
x = rand() % RANGE_X, y = rand() % RANGE_Y;
}
this->Game[x][y].value = -1;
seed->first = x; seed->second = y;
}
void Snake::RemoveTailElem(pair<int, int> *snakeTail, Node ** snakeTailLink)
{
if ((*snakeTailLink)->link)
{
Node *p = (*snakeTailLink)->link;
(*snakeTailLink)->value = 0;
(*snakeTailLink)->link = NULL;
*snakeTailLink = p;
int x = (p - &Game[0][0]) / (RANGE_Y), y = (p - &Game[0][0]) % (RANGE_Y);
snakeTail->first = x;
snakeTail->second = y;
}
}
void Snake::AddHeadElem(pair<int, int> *snakeHead, Node ** snakeHeadLink, const int Key)
{
Node *p = Get_p_ElemOnNode(*snakeHead, Key);
int pos_x = 0, pos_y = 0;
p->value = (*snakeHeadLink)->value + 1;
(*snakeHeadLink)->link = p;
*snakeHeadLink = p;
PosToNext(&pos_x, &pos_y, p);
snakeHead->first = pos_x;
snakeHead->second = pos_y;
}
void Snake::PosToNext(int * pos_x, int * pos_y, Node* snakeItemLink)
{
*pos_x = (snakeItemLink - &Game[0][0]) / (RANGE_Y), *pos_y = (snakeItemLink - &Game[0][0]) % (RANGE_Y);
}
Snake::Node * Snake::Get_p_ElemOnNode(const pair<int, int> intHead, const int Key)
{
int Pos_x, Pos_y;
Pos(&Pos_x, &Pos_y, intHead);
if (Pos_x == -1 && Key == 3)
return &this->Game[RANGE_X - 1][intHead.second];
else if (Pos_x == 1 && Key == 4)
return &this->Game[0][intHead.second];
else if (Pos_y == -1 && Key == 2)
return &this->Game[intHead.first][RANGE_Y - 1];
else if (Pos_y == 1 && Key == 1)
return &this->Game[intHead.first][0];
else
{
switch (Key)
{
case 3:return &this->Game[intHead.first - 1][intHead.second];
case 4:return &this->Game[intHead.first + 1][intHead.second];
case 2:return &this->Game[intHead.first][intHead.second - 1];
case 1:return &this->Game[intHead.first][intHead.second + 1];
default:
break;
}
}
}
void Snake::BuildWall(int i)
{
switch (i)
{
case 1:
for (int i = 0; i < RANGE_X; i++)
{
this->Game[i][0].value = this->Game[i][RANGE_Y - 1].value = -2;
}
for (int i = 0; i < RANGE_Y; i++)
{
this->Game[0][i].value = this->Game[RANGE_X - 1][i].value = -2;
}
break;
default:
break;
}
}
#pragma once
#include"cstring"
#include"stdlib.h"
#include"time.h"
#include"cocos2d.h"
#include "GameScene.h"
#define RANGE_X 48
#define RANGE_Y 32
using namespace std;
USING_NS_CC;
class Snake :public cocos2d::Sprite
{
public:
struct Node
{
int value;
Node *link;
};
static Snake* createWithSnake(cocos2d::Node * pnt);//创建
bool Move(float dt);
int Key; //up 1 down 2 left 3 right 4;
cocos2d::Node * Parent;
int length = 0;//蛇长度
private:
Snake(cocos2d::Node* Parent);
Node Game[RANGE_X][RANGE_Y];
void Printf(int i, Node* snakeTailLink, Node* snakeHeadLink);// 0表示需要重绘种子
pair<int, int> snakeHead, snakeTail, seed;
Node* snakeHeadLink, *snakeTailLink;
void Pos(int *pos_x, int *pos_y, const pair<int, int>intElem);//获取元素位置信息
int Get_p_ElemOnKey(const pair<int, int>intHead, const int Key);//返回蛇头目标方向的值
void Seed(pair<int, int> *seed);//修改种子
void RemoveTailElem(pair<int, int>*snakeTail, Node** snakeTailLink);//移除蛇尾
void AddHeadElem(pair<int, int>*snakeHead, Node** snakeHeadLink,const int Key);//添加蛇头
void PosToNext(int * pos_x, int * pos_y, Node* snakeItemLink);
Node* Get_p_ElemOnNode(const pair<int, int> intHead, const int Key);
void BuildWall(int i);//i 关卡
};