笔试编程题--贪吃蛇问题

博客围绕贪吃蛇游戏笔试展开,介绍了游戏玩法,指出其核心是用链表节点位置和个数描述蛇的信息。给出不考虑吃果子时,贪吃蛇移动一格对链表的高效操作方法,还要求实现考虑吃果子和碰撞自身情况的移动函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

贪吃蛇游戏笔试

贪吃蛇游戏是一款耳熟能详的小游戏,通过上下左右控制蛇的方向,寻找吃的果子,每吃一口果子,蛇的身子会越吃越长,身子越长玩的难度就越大,不能碰墙,不能咬到自己的身体,更不能咬自己的尾巴,吃完所有果子,就能过关,然后继续玩下一关。
该游戏的核心是通过链表中的节点位置(假设节点中的x,y来表示节点所在的位置信息)和节点个数来描述蛇的长度和身体位置信息,移动方向即控制链表节点的位置信息。假设节点之间采用双向链表的形式进行连接。根据上述描述:

(1)请简要回答在不考虑吃到果子的前提下,贪吃蛇每上下左右移动一格,设计时如何对链表操作能达到高效的移动?

  • 保存蛇尾前一节点位置数据
  • 蛇尾接受新位置数据
  • 断开蛇尾,蛇尾接在蛇头之前
  • 新蛇头为蛇尾,新蛇尾为保存节点数据
SLIST_S *current = pTailSnake->prev;//保存蛇尾上一节点
        //将位置数据更新到蛇尾
        pTailSnake->x=pFood->x;
        pTailSnake->y=pFood->y;
        //将蛇尾断开
        pTailSnake->prev->next=NULL;
        pTailSnake->prev=NULL;
        //将蛇尾接到蛇头之前
        pTailSnake->next=pHeadSnake;
        pHeadSnake->prev=pTailSnake;
        //新蛇头即为蛇尾
        pHeadSnake = pTailSnake;
        //新蛇尾为之前保存的数据
        pTailSnake = current;

(2)请实现贪吃蛇移动的函数,考虑移动时分别当吃到果子和没有吃的果子的场景,同时还要判断在移动一步之后是否会造成碰到蛇自己本身(不考虑碰壁),即当蛇的头部碰到蛇身体任何部分即表示失败。

int SnakeMove(Food_S *pFood,  SLIST_S *pHeadSnake,  SLIST_S *pTailSnake);
/*函数说明:
参数pFood:作为入参表示蛇下一个移动的位置,当成员IsHaveFood为FLASE时表示仅仅只是移动位置,当IsHaveFood为TRUE时,表示吃到了果子;
参数pHeadSnake、pTailSnake:分别表示贪吃蛇的头尾节点,即是入参也是出参;
返回值:表示贪吃蛇移动函数的结果是成功还是失败,0表示成功, -1表示失败;*/
typedef struct SLIST{
	  int x;
    int y;
	  struct SLIST *prev;
	      struct SLIST *next;
    }SLIST_S;
typedef struct Food{
	  int x;
    int y;
	      bool IsHaveFood;
}Food_S;
#include <stdio.h>
#include <stdbool.h>
#include <malloc.h>
typedef struct SLIST {
    int x;
    int y;
    struct SLIST *prev;
    struct SLIST *next;
} SLIST_S;

typedef struct Food {
    int x;
    int y;
    bool IsHaveFood;
} Food_S;

// 贪吃蛇移动函数
int SnakeMove(Food_S *pFood, SLIST_S *pHeadSnake, SLIST_S *pTailSnake) {
    // 吃到了果子
    if (pFood->IsHaveFood == true) {
        // 在蛇头位置添加新的节点
        SLIST_S *newNode = (SLIST_S *)malloc(sizeof(SLIST_S));
        //新节点接受位置信息
        newNode->x = pFood->x;
        newNode->y = pFood->y;
        //将节点接到蛇头之前
        newNode->prev = NULL;
        newNode->next = pHeadSnake;
        pHeadSnake->prev = newNode;
        //新蛇头为新增节点
        pHeadSnake = newNode;
        pFood->IsHaveFood = false; // 吃到果子后标记为没有果子
    }
    // 没有吃到果子
    if (pFood->IsHaveFood == false) {
        SLIST_S *current = pTailSnake->prev;//保存蛇尾上一节点
        //将位置数据更新到蛇尾
        pTailSnake->x=pFood->x;
        pTailSnake->y=pFood->y;
        //将蛇尾断开
        pTailSnake->prev->next=NULL;
        pTailSnake->prev=NULL;
        //将蛇尾接到蛇头之前
        pTailSnake->next=pHeadSnake;
        pHeadSnake->prev=pTailSnake;
        //新蛇头即为蛇尾
        pHeadSnake = pTailSnake;
        //新蛇尾为之前保存的数据
        pTailSnake = current;
    }
    // 检查是否碰到蛇身体
    SLIST_S *current = pTailSnake;
    while (current != pHeadSnake) {
        if (current->x == pHeadSnake->x && current->y == pHeadSnake->y) {
            return -1; // 碰到蛇身体,移动失败
        }
        current = current->prev;
    }

    return 0; // 移动成功
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值