贪吃蛇笔记.c(链表学习)

gotoxy光标函数

void gotoxy(int x, int y)
{
    // 更新光标位置
    COORD pos;
    HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    pos.X = x;
    pos.Y = y;
    SetConsoleCursorPosition(hOutput, pos);
    // 隐藏光标
    CONSOLE_CURSOR_INFO cursor;
    cursor.bVisible = FALSE;
    cursor.dwSize = sizeof(cursor);
    SetConsoleCursorInfo(hOutput, &cursor);
}//以左上角为原点,向右为x轴正方向,向下为y轴正方向

/**********************************************************/
void gotoprint(int x, int y)
{
    gotoxy(x, y);
    printf("■");
}

/**********************************************************/
void gotodelete(int x, int y)
{
    gotoxy(x, y);
    printf("  ");
}


正方形宽2高1
在这里插入图片描述

main函数

关于system函数

int main()
{
	#include<stdio.h>
#include<string.h>
#include<windows.h>
#include<time.h>
#include<conio.h>

#define up 'w'
#define down 's'
#define left 'a'
#define right 'd'
#define false 0
#define true  1

typedef char bool;
void welcome();               // 开始界面
void Finish();                // 结束界面
void creatgraph();            // 围墙打印
void gotoxy(int x, int y);    // 光标跳转,横为X 0,1,2..
void gotoprint(int x, int y); // 跳转打印
void gotodelete(int x, int y);// 跳转删除
void creatfood();             // 食物产生
int ClickControl();           // 获取键盘信号
int Judge();                  // 游戏结束判断
void MovingBody();            // 蛇的移动
void Eating();                // 蛇吃到东西后的操作(伸长)
void ChangeBody(int x, int y); // 蛇的坐标变换

/*全局变量 + 预处理:*/
typedef struct Snakes
{
    int x;
    int y;
    struct Snakes* next;
}snake;//蛇链表

snake* head;    // 声明蛇头指针

// 申明并定义食物
struct Food
{
    int x;
    int y;
}food;//失误结构体

char name[20];  // 保存用户名 有兴趣可以制作登录系统
int score = 0;  // 分数
char click = 1; // 记录敲下的键盘按键
int speed;      // 速度 其实是延迟的毫秒数

/************************************************************/
    system("color 7d"); // 设置控制台字体颜色
    welcome();          // 欢迎界面
    creatgraph();       // 创建地图
    creatfood();        // 新建食物
    // 捕获鼠标按键 ClickControl
    if (ClickControl() == 0) return 0;
    return 0;
}


welcome函数

void welcome()//一系列移动光标打印过程
{
    gotoxy(15, 10);
    printf("/**********************************************/");
    gotoxy(15, 20);
    printf("/**********************************************/");
    gotoxy(20, 13);
    printf("WELCOME TO THE GAME OF RETRO SNAKE");
    gotoxy(14, 16);
    printf("请在英文输入法中操作,反向移动等同于吃到自己,wasd控制p暂停");
    gotoxy(20, 18);
    printf("PLEASE ENTER YOUR NAME:");
    scanf("%s", &name, 20);
    system("cls");
}

围墙函数

void creatgraph() {
    int i;
    /*
    注意这里横坐标是每次+2 因为控制台字符宽高比为1:2
    */
    for (i = 0; i < 58; i += 2)//x轴方向
    {
        gotoprint(i, 0);//上围墙
        gotoprint(i, 26);//下围墙
    }
    for (i = 1; i < 26; i++)
    {
        gotoprint(0, i);//左围墙
        gotoprint(56, i);//右围墙
    }
    gotoxy(63, 10);
    printf("hello %s,Welcome To Play", name);
    gotoxy(63, 15);
    printf("Your Score Is:%d    = ̄ω ̄= ", score);
    gotoxy(63, 20);
    printf("This Game Is Created By 炫");
    head = (snake*)malloc(sizeof(snake));//构建蛇身链条
    snake* p = (snake*)malloc(sizeof(snake));
    snake* q = (snake*)malloc(sizeof(snake));
    head->x = 16;
    head->y = 15;
    p->x = 16;
    p->y = 16;
    q->x = 16;
    q->y = 17;
    head->next = p;
    p->next = q;
    q->next = NULL;
}

产生随机食物函数

srand函数和rand函数的运用

void creatfood()
{
    // 随机产生一个食物
    bool flag = false;
    while (!flag)
    {
        flag = true;
        srand((int)time(NULL));
        food.y = rand() % (25 - 1 + 1) + 1;
        food.x = rand() % (54 - 2 + 1) + 2;//见上面链接
        
        if (food.x % 2 != 0)//判断横坐标是否为偶数,正方形的宽为2
        {
            food.x = food.x + 1;
        }
        snake* judge = head;//赋值judge以蛇头地址
        while (1)  //遍历排除蛇身重复
        {
            if (judge->next == NULL) break;//蛇尾结束退出循环
            if (food.x == judge->x && food.y == judge->y)
            {
                flag = false;
            }
            judge = judge->next;//一节一节地判断
        }
    }
    gotoxy(food.x, food.y);
    printf("⊙");
}

吃食物加一个方框

void Eating()
{
    if (head->x == food.x && head->y == food.y)
    {
        creatfood();
        snake* _new = (snake*)malloc(sizeof(snake));
        snake* p;
        p = head;
        while (1)
        {
            if (p->next == NULL) break;
            p = p->next;
        }//p为蛇尾
        p->next = _new;//将吃食物新增的方块加在蛇尾
        _new->next = NULL;
        score += 10;
        gotoxy(77, 15);
        printf("%d", score);
    }
}

更新蛇体坐标

void ChangeBody(int x, int y)
{
    snake* p = head;
    while (p->next->next != NULL) {
        p = p->next;
    }//循环到倒数第二个方块
    free(p->next);//释放最后一个方块
    p->next = NULL;//赋值最后一个方块的next为NULL
    snake* new_head = (snake*)malloc(sizeof(snake));//新建内存作为新的蛇头
    new_head->x = x;
    new_head->y = y;
    new_head->next = head;//将旧的蛇头接到新头上
    head = new_head;//将全新的蛇的首地址重新赋值给head
}

判断是否游戏结束

int Judge()
{
    if (head->x == 0 || head->x == 56 || head->y == 0 || head->y == 26)
    {
        Finish();
        return 0;
    }//如果碰到墙则结束游戏
    snake* p = head->next;//蛇头后面那一个方块
    while (1)
    {
        if (p == NULL) break;
        if (head->x == p->x && head->y == p->y)//蛇头如果碰到自己的蛇身
        {
            Finish();
            return 0;
        }
        p = p->next;//每一节蛇身判断是否碰到
    }
    return 1;
}

click函数检测输入的值

关于——kbhit函数的解释

int ClickControl()
{
    char c;
    while (1)
    {
        if (Judge() == 0) return 0;//如果判断触发结束条件,游戏结束
        if (_kbhit())//此函数为非阻塞函数,如果按键按下返回非0值,否则返回0值
        {
            click = _getch();
        }
        MovingBody();
        Eating();
    }
    return 1;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值