简单贪吃蛇

主要使用链表的知识,怎么让蛇动起来呢?其实就只需要每次在它前进的方向上插入一个头结点再删除一个尾节点就可以动起来了,变长就不删除尾节点就可以了;(经过多次修改,仍然有些bug,不过不想再深究了)以下是源代码:


#include<iostream>
#include<stdlib.h>
#include<string.h>
#include<Windows.h>
#include<conio.h>
#include<time.h>
using namespace std;

char map[20][20];

enum dir { up, down, leftw, rightw };//方向

dir point;//记录贪吃蛇运动方向

int food_x, food_y;

typedef struct node
{
    int i;
    int j;
    node *next, *prior;
}Snakenode;

Snakenode *head = NULL, *tail = NULL;

void InitFence()//画地图
{
    for (int i = 0; i<20; i++)
        for (int j = 0; j<20; j++)
        {
            if (i == 0 || i == 19)
                map[i][j] = '-';
            else if (j == 0 || j == 19)
                map[i][j] = '|';
            else map[i][j] = ' ';
        }
    map[0][0] = '#';
    map[0][19] = '#';
    map[19][0] = '#';
    map[19][19] = '#';
}

void Output()//显示地图
{
    for (int i = 0; i < 20; i++)
    {
        for (int j = 0; j < 20; j++)
            cout << map[i][j] << " ";
        cout << endl;
    }
}

int get_i(Snakenode *&L)
{
    return L->i;
}

int get_j(Snakenode *&L)
{
    return L->j;
}

void add_head(int x, int y, Snakenode *&L)//插入头结点
{
    Snakenode *q;
    int p, k;
    q = new Snakenode;
    q->i = x;
    q->j = y;
    q->next = head;
    q->prior = NULL;
    if (head != NULL)
    {
        head->prior = q;
        p = get_i(head);
        k = get_j(head);
        map[p][k] = '*';
    }
    head = q;
    if (tail == NULL)
        tail = head;
    map[x][y] = '@';//@是贪吃蛇的头
    L = head;
}

void delete_tail()//删除尾节点
{
    Snakenode *p = tail;
    map[get_i(tail)][get_j(tail)] = ' ';
    if (tail == head)
        tail = head = NULL;
    else
    {
        tail = tail->prior;
        tail->next = NULL;
    }
    delete p;
}

void change_point(char keydown)//变向且不能掉头
{
    switch (keydown)
    {
    case 'w': if (point != up&&point != down) point = up; break;
    case 's': if (point != up&&point != down) point = down; break;
    case 'a': if (point != rightw&&point != leftw) point = leftw; break;
    case 'd': if (point != rightw&&point != leftw) point = rightw; break;
    }
}

int get_food()
{
    srand((unsigned int)time(NULL));//做种子
    food_x = rand() % 18 + 1;
    food_y = rand() % 18 + 1;
    if (map[food_x][food_y] - '*' == 0 || map[food_x][food_y] - '@' == 0)
        return 0;
    map[food_x][food_y] = '$';
    return 1;
}

void moving()//移动
{
    int a, b;
    a = get_i(head);
    b = get_j(head);
    switch (point)
    {
    case up:--a; break;
    case down:++a; break;
    case leftw:--b; break;
    case rightw:++b; break;
    }
    if (a == 19 || b == 19 || a == 0 || b == 0)//撞墙
    {
        cout << "game over!!!" << endl;
        exit(0);
    }
    if (map[a][b] == '*')//咬到自己
    {
        cout << "game over!!!" << endl;
        exit(0);
    }
    if (a == food_x && b == food_y)//吃到食物
    {
        add_head(a, b, head);//长长
        while(1)
        { 
            if (get_food() == 1)
                break;
        }
    }
    else//移动
    {
        add_head(a, b, head);
        delete_tail();
    }

}

int main()
{
    cout << "使用 w s a d 控制上下左右!!!\n按任意键开始游戏!!" << "\n\n\n";
    InitFence();
    int a, b;
    a = rand() % 10 + 4;
    b = rand() % 10 + 4;
    add_head(a, b, head);
    add_head(a, b + 1, head);
    add_head(a, b + 2, head);
    while(1)
    { 
        if (get_food() == 1)
            break;
    }
    Output();
    int p = rand() % 4;//初始化方向
    switch (p)
    {
    case 0:point = up; break;
    case 1:point = down; break;
    case 2:point = leftw; break;
    case 3:point = rightw; break;
    }
    while (1)
    {
        char keydown = getch();//返回键盘上读取的字符
        change_point(keydown);
        while (!kbhit())//检查当前是否有键盘输入,若有则返回一个非0值,否则返回0
        {
            system("cls");//清屏函数;
            moving();
            Output();
            Sleep(800);//挂起一段时间
        }
    }
    return 0;
}

这里写图片描述

猜你喜欢

转载自blog.csdn.net/tron_future/article/details/51290693