贪吃蛇的设计(1)(无界面版本)

[0]移动模块:贪吃蛇移动的方向(上,下,左,右),注意不能朝反方向进行移动.每次移动需要检测是否撞到边界或者吃到自己。每一个节点都往前进一步.

/******返回false代表失败*************/
bool Snake::move(string ms)
{
/************处理头部的坐标变换************/
    auto iter = data.begin();
    position last = (*iter);//记录上一个节点的坐标
    auto test_x = iter->x + direction[ms].x;
    auto test_y = iter->y + direction[ms].y;
    /*判断是非朝反方向走*/
    if (data[1].x == test_x&&data[1].y == test_y)
        return true;//朝反方向
    else if (!(isgood(test_x) && isgood(test_y)))
        return false;//撞墙
    else //新节点正常
        *iter = position(test_x, test_y);

    auto original_x =iter->x, original_y = iter->y;
    /*************新的首节点不能和剩下的节点冲突*************************/
    while (++iter != data.end())
    {
        position temp = *iter;
        *iter = last;//这个节点的坐标变成上一个节点
        last = temp;
        if (original_x == iter->x && original_y == iter->y)//节点冲突,结束
            break;
    }
    return iter==data.end();
}

[1]类的设计:

class position
{
public:
    position() :x(0), y(0){}
    position(int a, int b) :x(a), y(b){}
    int x;
    int y;
};
class Snake
{

public:
    /**********构造函数**********/
    Snake(int n) :N(n){}
    bool move(string);
    void display();
    inline void add_node(int x, int y){ data.push_back(position(x, y)); }

private:
    const int N;//活动区域的大小: N*N
    vector<position> data;
    static map<string, position> direction;
    inline bool isgood(int x){ return (x != -1 && x != N); }

};

[2]:显示,没有界面设计的情况下就只能用控制台显示了,首先进行对节点按坐标(先排横坐标,再排纵坐标)排序,然后用*显示出来:

bool isless(position a, position b){
    if (a.x < b.x)
        return true;
    else if (a.x > b.x)
        return false;
    else return a.y < b.y;
}
void Snake::display()
{

    auto displayer_data = data;
    sort(displayer_data.begin(), displayer_data.end(), isless);
    auto last = displayer_data.begin();
    cout << string(N - 1, '=') << string(last->x,'\n');
    cout << string(last->y, ' ')<<"*";//输出第一个
    int count = 0;
    for (auto beg = displayer_data.begin()+1; beg != displayer_data.end(); ++beg,++last)
    {

        if (beg->x != last->x)
            cout << endl << string(beg->y, ' ')<<"*";
        else
            cout << string(beg->y - last->y-1, ' ')<<"*";
    }       
    cout << string(N - 1 - last->x, '\n') << string(N - 1, '=');
}

[3]:main函数:每隔3个移动就增加一个尾部节点.

int main()
{
    Snake game(25);
    for (int i = 0; i != 7; ++i)
        game.add_node(7, i);
    string ms;
    int count = 0;
    while (cin >> ms&&game.move(ms))
    {
        game.display();
        if (!(++count % 3))
            game.add_node(game.lastnode.x,game.lastnode.y);
    }
    cout << "game over\n";
    return 0;
}

贪吃蛇的设计(1)(无界面版本)_第1张图片

贪吃蛇的设计(1)(无界面版本)_第2张图片

贪吃蛇的设计(1)(无界面版本)_第3张图片

贪吃蛇的设计(1)(无界面版本)_第4张图片

贪吃蛇的设计(1)(无界面版本)_第5张图片

你可能感兴趣的:(贪吃蛇的设计(1)(无界面版本))