鱼C论坛

 找回密码
 立即注册
查看: 2533|回复: 14

[技术交流] 贪吃蛇(纯c编写,新手请进)

[复制链接]
发表于 2017-3-17 16:12:23 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 qwe1231069 于 2017-3-18 11:37 编辑

我花了好几天写了这玩意(第一次写),我敢保证这游戏写的是最烂的。玩了一会,游戏体验太差。反正是给咱们新手看的,无所谓了。能玩就行了。

首先我是参考1012662902的帖子http://bbs.fishc.com/thread-49160-1-1.html(虽然有些依旧不懂,留着吧。后面再看看再改)
遇到了一些问题,也有好心人解答。@人造人和@lumber2388779(回帖我给你们评分哦)

由于好些地方代码写的不好,所以吃掉一个后要再按一下方向键才出现下一个。wasd(小写控制移动),任意键暂停。
还有好多应该改进的地方,因为我太懒了所以就拖着吧。
#include <stdio.h>
#include <stdlib.h>
#include<windows.h>
#include <conio.h>
#include<time.h>

#define WX 50
#define WY 23

void gotoxy(int x, int y);


typedef struct snake{
int x;
int y;
int length;
struct snake *next;
}snake, *Snake;

typedef struct food{
int x;
int y;
struct food *next;
}food, *Food;

void clean(Snake head);
void test(Snake head);
int getvalue(Snake o, int n);
int getvaluey(Snake o, int n);
void changevalue(Snake n, int i, int s);
void changevaluey(Snake n, int i, int s);
void control(Snake a);
void auto_move(Snake head,char direction, Food k);
void *show_food(Snake head);
int getlength(Snake k);
void the_end(Snake head);
int f = 0;//是否有食物

//创建动态链表,在链表末尾添加一个x,y坐标
void createL(Snake head, int x, int y)
{
    Snake swap, newl;
    swap = head;
    while(swap->next != NULL)
    {
        swap = swap->next;
    }

    newl = (Snake) malloc(sizeof(snake));
    if(newl == NULL )
    {
        printf("error\n");
    }
    newl->x = x;
    newl->y = y;
    newl ->length = swap ->length + 1;
    swap->next = newl;
    newl->next = NULL;

}
void* _snake()//初始化蛇
{
    int i;
    Snake head;
    head =(Snake) malloc(sizeof(snake));
    head->next = NULL;
    head->x = 8;
    head->y = 3;
    head ->length = 1;

    for(i = 0; i < 3; i++)
    {
        createL(head, 7 - i, 3);
    }
    return (head);

}


void draw_snake(Snake head)
{
    gotoxy(head->x, head->y);
    putchar('@');//这是脑袋
    head = head->next;
    for( ;head->next != NULL;head = head->next)
    {
        gotoxy(head->x, head->y);
        putchar('*');//这是身体
    }
    gotoxy(head->x, head->y);
    putchar('*');//这是尾巴
}

int getlength(Snake head)
{
    Snake swap = head;
    int n = 0;
     for( ; swap->next != NULL ;swap = swap ->next)
         {
             n = swap->length;
             /** 不包括蛇头 n 是蛇身的长度
             */
         }
         return n;
}
void *show_food(Snake head)
{
    srand(time(NULL));
    Food apple;

    apple = (Food)malloc(sizeof(food));
    apple ->next = NULL;
    while(1)
    {
        apple -> x = rand() % (WX - 1) + 1;
        apple -> y = rand() % (WY - 1) + 1;
        while(head ->next != NULL)
        {
            if(head->x == apple->x || head->y == apple->y)
                break;
            head = head ->next;
        }
        break;
    }

    gotoxy(apple -> x, apple -> y);
    putchar('#');

    return (apple);
}
int getvalue(Snake swap, int n)
{
    while(n--)
    {
        swap = swap ->next;
    }
    return swap->x;
}

int getvaluey(Snake swap, int n)
{
    while(n--)
    {
        swap = swap ->next;
    }
    return swap->y;
}

void changevalue(Snake swap, int i, int n)
{
   while(n--)
   {
       swap = swap ->next;
   }
   swap ->x = i;
}
void changevaluey(Snake swap, int i, int n)
{
   while(n--)
   {
       swap = swap ->next;
   }
   swap ->y = i;
}

void auto_move(Snake head,char direction,Food apple)
{
    Snake swap;
    int x = 0, y = 0, n = 0;
    while(!kbhit())
   {

       swap = head;//初始化不要忘了


        if(head ->x == apple->x && head ->y == apple->y)
        {
            f = 0;
            n = getlength(head);
            x = getvalue(swap,n);
            y = getvaluey(swap,n);/**不懂为啥n+ 1不对,还不太明白*/
            createL(head,x , y);
        }
        clean(head);//我先清理的所以刚开始蛇身只有两节
        /**
         *  把链表倒数第二个值赋值给倒数第一个
         *  这样就不会把值覆盖了
            最后一个链表存储当前蛇的长度
         */
         n = getlength(head);

        while(n--)
        {
            x = getvalue(swap,n);//得到第n个链表的值
            y = getvaluey(swap,n);
            changevalue(swap, x, n+1);//把第n个链表的值写入第n+1个链表
            changevaluey(swap, y, n+1);
        }
        switch(direction)
        {
            case 'w': head ->y -= 1;break;
            case 'a': head ->x -= 1;break;
            case 's': head ->y += 1;break;
            case 'd': head ->x += 1;break;
        }



        Sleep(160);
        draw_snake(head);
        the_end(head);
   }
}

void control(Snake head)
{
    char c, o = 0;
    Food apple;
    while(1)
    {
        if(!f)//判断是否有食物
        {
            f = 1;
            apple = show_food(head);
        }

       c = getch();
        if(c == 'w' || c == 'a' || c == 's' || c == 'd' )
        {
            if((c == 'w' && o != 's') || (c == 'a' && o != 'd') || (c == 'd' && o != 'a') || (c == 's' && o != 'w'))
                {
                    o = c;
                    auto_move(head, c, apple);
                }

        }

    }
}
void test(Snake head)
{
    for(; head->next != NULL;head = head->next )
    {
        printf("%d,%d\n",head->x,head->y);
    }
    printf("%d,%d\n",head->x,head->y);
}
void clean(Snake head)
{
    Snake swa;
    swa = head;
    while(swa->next != NULL)
    {
        swa = swa->next;
    }
    gotoxy(swa->x, swa->y);
    putchar(' ');
}

void the_end(Snake head)
{
    Snake swap = head;
    if(getlength(head) > 50)
    {
        system("cls");
        gotoxy(10,20);
        printf("YOU WIN!!");
        Sleep(2000);
        exit(0);
    }
    while(swap ->next != NULL)
    {
        swap = swap ->next;
        if(head ->x == swap ->x && head ->y == swap->y)
        {
            system("cls");
            gotoxy(10,20);
            printf("YOU DEATH!!");
            Sleep(2000);
            exit(0);
        }

    }
    if(head->x >= WX || head->y >= WY || head->x == 0 || head->y == 0)
    {
        system("cls");
        gotoxy(10,20);
        printf("YOU DEATH!!");
        Sleep(2000);
        exit(0);
    }
}
void gotoxy(int x, int y)//定义光标位置
{
    COORD wei;
    wei.X = x;
    wei.Y = y;
    //Windows±à3ì
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), wei);
}
void wall()
{
    int x,y;

    for(x = 0; x <= WX; x++)
    {
        if(x == 0 || x == WX)
        {
            for(y =0 ;y <= WY; y++)
            {
                gotoxy(x , y);
                printf("+");
            }
        }
        gotoxy(x, 0);
        printf("+");
        gotoxy(x, WY);
        printf("+");

    }

}
int main()
{
    Snake p;//链表头指针p

    wall();
     p = _snake();
    draw_snake(p);
    control(p);
    system("pause");
    return 0;
}

评分

参与人数 2荣誉 +7 鱼币 +7 贡献 +5 收起 理由
人造人 + 5 + 5 + 5 支持楼主!
lumber2388779 + 2 + 2 支持楼主!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-3-17 16:30:06 | 显示全部楼层

回帖奖励 +2 鱼币

好样的 我当年也是用ASCII打印实现的

评分

参与人数 1荣誉 +1 鱼币 +1 收起 理由
qwe1231069 + 1 + 1 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2017-3-17 19:34:05 | 显示全部楼层

回帖奖励 +2 鱼币

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-3-18 09:00:19 | 显示全部楼层

回帖奖励 +2 鱼币

感谢楼主   希望以后在配一张图更好
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-18 11:23:46 | 显示全部楼层

回帖奖励 +2 鱼币

學習學習
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-18 14:20:49 | 显示全部楼层

回帖奖励 +2 鱼币

我的编译器报错了啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-3-19 19:02:44 | 显示全部楼层
桃花飞舞 发表于 2017-3-18 14:20
我的编译器报错了啊

有的函数没声明
如果是其他原因,就不知道了
链表或者定义问题?你不发出错误原因,我猜不到
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-20 10:34:49 | 显示全部楼层

回帖奖励 +2 鱼币

好厉害,感觉学习新东西就要尝试应用,这样才能越学越有动力,向楼主学习~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-21 16:12:51 | 显示全部楼层
qwe1231069 发表于 2017-3-19 19:02
有的函数没声明
如果是其他原因,就不知道了
链表或者定义问题?你不发出错误原因,我猜不到

我现在看不了,等晚上可能了看下。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-24 10:34:24 | 显示全部楼层

回帖奖励 +2 鱼币

这么强,什么编译器
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-24 16:57:53 | 显示全部楼层

回帖奖励 +2 鱼币

复制代码玩了一下,感觉好萌,玩着挺开心的,谢谢楼主分享。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-27 23:28:11 | 显示全部楼层

回帖奖励 +2 鱼币

--------------------Configuration: test - Win32 Debug--------------------
Compiling...
test.c
D:\C语言练习缓存\test\test.c(109) : error C2275: 'Food' : illegal use of this type as an expression
        D:\C语言练习缓存\test\test.c(24) : see declaration of 'Food'
D:\C语言练习缓存\test\test.c(109) : error C2146: syntax error : missing ';' before identifier 'apple'
D:\C语言练习缓存\test\test.c(109) : error C2065: 'apple' : undeclared identifier
D:\C语言练习缓存\test\test.c(111) : warning C4047: '=' : 'int ' differs in levels of indirection from 'struct food *'
D:\C语言练习缓存\test\test.c(112) : error C2223: left of '->next' must point to struct/union
D:\C语言练习缓存\test\test.c(115) : error C2223: left of '->x' must point to struct/union
D:\C语言练习缓存\test\test.c(116) : error C2223: left of '->y' must point to struct/union
D:\C语言练习缓存\test\test.c(119) : error C2223: left of '->x' must point to struct/union
D:\C语言练习缓存\test\test.c(119) : error C2223: left of '->y' must point to struct/union
D:\C语言练习缓存\test\test.c(126) : error C2223: left of '->x' must point to struct/union
D:\C语言练习缓存\test\test.c(126) : error C2223: left of '->y' must point to struct/union
D:\C语言练习缓存\test\test.c(126) : error C2198: 'gotoxy' : too few actual parameters
D:\C语言练习缓存\test\test.c(129) : warning C4047: 'return' : 'void *' differs in levels of indirection from 'int '
执行 cl.exe 时出错.

test.obj - 1 error(s), 0 warning(s)
有错误啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-3-28 11:26:04 | 显示全部楼层

我不会改
像第一个错,你可以定义一个结构体,在定义一个结构体变量。看它报错不
如果报错就不是我的锅了,这锅要编译器来背。我用的 gcc -wall
不报错的话,就是我的过了。只能说我是新手水平太菜了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-28 18:43:39 | 显示全部楼层
qwe1231069 发表于 2017-3-28 11:26
我不会改
像第一个错,你可以定义一个结构体,在定义一个结构体变量。看它报错不
如果报错就不是我的锅 ...

我是用VC++6.0的,我也不清楚这错误是什么情况,我也是个菜鸟
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-2-26 00:15

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表