鱼C论坛

 找回密码
 立即注册
查看: 1350|回复: 16

[技术交流] 自己写第一个贪吃蛇游戏100%自己写的无cp

[复制链接]
发表于 2020-3-6 17:32:33 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 就是要努力呀 于 2020-3-31 18:08 编辑

是在linux里写的那几个system是对控制台的设置,为了让scanf不用回车就直接运行
wiondos上可以自己更改一下
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#define SNAKE 'o'
#define FOOD '*'
#define MAX 50

typedef struct Snake
{
        int x;        //蛇的x坐标
        int y;        //蛇的y坐标
        struct Snake *per;
        struct Snake *next;
}
Snake;

int COUNT = 1;        //蛇的长度
Snake *HEAD = NULL, *TAIL = NULL;        //蛇的头尾指针
char FOOD_MAP[MAX][MAX];
char MAP[MAX][MAX];

void prinmain(void);        //打印主菜单
void MAP_set_up(void);        //生成地图
void FOOD_MAP_set_up(void);        //生成食物地图
void snake_set_up(void);        //生成蛇
void put_snake(void);        //将蛇放置在地图中
void reset_MAP(void);        //刷新地图
void print_all(void);        //打印所有物品
int do_move(char move);        //判断蛇的移动
int check_cross(void);        //检测蛇是否越界
int check_kill(void);        //检测蛇是否碰到自己
int check_food(void);        //检测蛇是否吃到食物
void snake_add(char move);        //增加蛇的长度
void game_over();        //游戏结束,释放链表

void game_over()        //游戏结束,释放链表
{
        Snake *temp;

        while(HEAD != NULL)
        {
                temp = HEAD->next;
                free(HEAD);
                HEAD = temp;
        }
}

void snake_add(char move)        //增加蛇的长度
{
        Snake *new;

        new = (Snake *)malloc(sizeof(Snake));

        if(new == NULL)
        {
                printf("生成蛇失败!\n");

                exit(0);
        }

        switch(move)
        {
                case 'w':
                        new->x = TAIL->x + 1;
                        new->y = TAIL->y;

                        break;

                case 'a':
                        new->y = TAIL->y + 1;
                        new->x = TAIL->x;
                        
                        break;

                case 's':
                        new->x = TAIL->x - 1;
                        new->y = TAIL->y;

                        break;

                case 'd':
                        new->y = TAIL->y - 1;
                        new->x = TAIL->x;

                        break;
        }

        TAIL->next = new;
        new->next = NULL;
        TAIL = new;
}

int check_food(void)        //检测蛇是否吃到食物
{
        if(FOOD_MAP[HEAD->x][HEAD->y] == FOOD)
        {
                FOOD_MAP[HEAD->x][HEAD->y] = ' ';

                return 1;
        }

        return 0;
}

int check_kill(void)        //检测蛇是否碰到自己
{
        Snake *temp;

        temp = HEAD->next;

        while(temp != NULL)
        {
                if(HEAD->x == temp->x && HEAD->y == temp->y)
                {
                        return 0;
                }

                temp = temp->next;
        }

        return 1;
}

int check_cross(void)        //检测蛇是否越界
{
        if(HEAD->x == 0 || HEAD->x == MAX - 1 || HEAD->y == 0 || HEAD->y == MAX - 1)
        {
                return 0;
        }

        return 1;
}

int do_move(char move)        //判断蛇的移动
{
        int tempxy[COUNT][2];
        int i = 0;
        Snake *temp;

        memset(tempxy, '0', COUNT * 2);

        if(move == 'w' || move == 'a' || move == 's' || move == 'd')
        {
                temp = HEAD;

                while(temp != NULL)
                {
                        tempxy[i][0] = temp->x;
                        tempxy[i][1] = temp->y;

                        i++;

                        temp = temp->next;
                }

                i = 0;

                temp = HEAD->next;

                while(temp != NULL)
                {
                        temp->x = tempxy[i][0];
                        temp->y = tempxy[i][1];

                        i++;

                        temp = temp->next;
                }

                temp = HEAD;


                switch(move)
                {

                        case 'w':
                                HEAD->x = tempxy[0][0] - 1;

                                break;

                        case 'a':
                                HEAD->y = tempxy[0][1] - 1;

                                break;

                        case 's':
                                HEAD->x = tempxy[0][0] + 1;

                                break;

                        case 'd':
                                HEAD->y = tempxy[0][1] + 1;

                                break;
                }

                if(!check_cross())
                {
                        return 0;
                }

                if(!check_kill())
                {
                        return 0;
                }

                if(check_food())
                {
                        COUNT++;

                        snake_add(move);
                }
        }
        else if(move == 'q')
        {
                return 0;
        }

        return 1;
}

void print_all(void)        //打印所有物品
{
        static int count = 0;

        printf("当前得分:%d\n", COUNT);

        if(COUNT - count == 4)
        {
                FOOD_MAP_set_up();

                count = COUNT;
        }

        reset_MAP();
        put_snake();

        for(int i = 0; i < MAX; i++)
        {
                for(int j = 0; j < MAX ; j++)
                {
                        if(FOOD_MAP[i][j] != ' ')
                        {
                                printf("%c ", FOOD_MAP[i][j]);
                        }
                        else printf("%c ", MAP[i][j]);
                }

                putchar('\n');
        }
}

void reset_MAP(void)        //刷新地图
{
        for(int i = 1; i < MAX - 1; i++)
        {
                for(int j = 1; j < MAX - 1; j++)
                {
                        MAP[i][j] = ' ';
                }
        }
}

void put_snake(void)        //将蛇放置在地图中
{
        Snake *temp;

        temp = HEAD->next;

        MAP[HEAD->x][HEAD->y] = 'c';

        while(temp != NULL)
        {
                MAP[temp->x][temp->y] = SNAKE;

                temp = temp->next;
        }
}

void snake_set_up(void)        //生成蛇
{
        HEAD = (Snake *)malloc(sizeof(Snake));

        if(HEAD == NULL)
        {
                printf("生成蛇失败!\n");

                exit(0);
        }

        srand(time(NULL) + 1);

        do
        {
                HEAD->x = rand()%MAX;
                HEAD->y = rand()%MAX;
        }
        while(HEAD->x == 0 || HEAD->x == MAX - 1 || HEAD->y == 0 || HEAD->y == MAX - 1);

        HEAD->next = NULL;
        TAIL = HEAD;
}

void FOOD_MAP_set_up(void)        //生成食物地图
{
        int i = 0, x, y;

        memset(FOOD_MAP, ' ', MAX * MAX);

        srand(time(NULL));

        do
        {
                i++;

                do
                {
                        x = rand()%MAX;
                        y = rand()%MAX;
                }
                while(x == 0 || x == MAX - 1 || y == 0 || y == MAX - 1);

                FOOD_MAP[x][y] = FOOD;
        }
        while(i != 4);
}

void MAP_set_up(void)        //生成地图
{
        memset(MAP, ' ', MAX * MAX);

        for(int i = 0; i < MAX; i++)
        {
                for(int j = 0; j < MAX; j++)
                {
                        if(i == 0 || j == 0 || i == MAX - 1 || j == MAX - 1)
                        {
                                MAP[i][j] = '0';
                        }
                        else MAP[i][j] = ' ';
                }
        }
}

void prinmain(void)        //打印主菜单
{
        printf("1.开始游戏\n");
        printf("2.结束游戏\n");
        printf(":");
}

int main(void)
{
        char move;


        prinmain();
        scanf("%c", &move);
        getchar();

        if(move == '1')
        {
                MAP_set_up();
                FOOD_MAP_set_up();
                snake_set_up();

                do
                {
                        system("clear");
                        print_all();

                        printf("请输入指令(w/a/s/d/q):");

                        system("stty raw -echo");

                        scanf("%c", &move);

                        system("stty cooked echo");
                }
                while(do_move(move));
        }


        printf("\n游戏结束\n");

        system("stty cooked echo");

        game_over();

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

使用道具 举报

发表于 2020-3-6 17:35:07 | 显示全部楼层
贴代码用 "<>"
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-6 17:36:52 | 显示全部楼层

什么意思。。没懂
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-6 17:38:57 | 显示全部楼层

哦哦知道了谢谢提醒
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-6 17:45:54 | 显示全部楼层
大家可以给我说一下有什么清屏的函数
因为不知道所以我就用的linux控制台的clear命令
画面出来就是一张一张的
不过也不影响玩
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-6 18:20:15 | 显示全部楼层
就是要努力呀 发表于 2020-3-6 17:45
大家可以给我说一下有什么清屏的函数
因为不知道所以我就用的linux控制台的clear命令
画面出来就是一张一 ...

如果刷新频率不够,那就不要清屏,用gotoxy
https://bbs.csdn.net/topics/390687230
#include <stdio.h>

int main(void)
{
        printf("%c[%d;%df", 0x1b, 10, 10);
        printf("hello\n");
        return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-6 18:28:20 | 显示全部楼层
人造人 发表于 2020-3-6 18:20
如果刷新频率不够,那就不要清屏,用gotoxy
https://bbs.csdn.net/topics/390687230

ok谢谢我去学习一下
不知道怎么用
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-7 18:47:57 | 显示全部楼层
代码抄完之后,排了下错,就成了下面这样了,但为什么我抄的代码不能玩呢?
#include <stdio.h>
#include <stdbool.h>
#include <time.h> 

#define SNAKE 'O'
#define FOOD '*'
#define MAX 50

typedef struct Snake
{
                int x;                //蛇的x坐标
                int y;                //蛇的y坐标
                struct Snake *per;
                struct Snake *next; 
}
Snake;

int COUNT = 1;                //蛇的长度 
Snake * HEAD = NULL, *TAIL = NULL;                //蛇的头尾指针 
char FOOD_MAP [MAX][MAX];
char MAP[MAX][MAX];

void prinmain(void);                        //打印主菜单 
void MAP_set_up(void);                         //生成地图 
void FOOD_MAP_set_up(void);                //生成食物地图 
void snake_set_up(void);                //生成蛇 
void put_snake(void);                        //将蛇放置在地图中 
void reset_MAP(void);                        //刷新地图 
void print_all(void);                        //打印所有物品 
int do_move(char move);                        //判断蛇的移动 
int check_cross(void);                        //检测蛇是否越界 
int check_kill(void);                        //检测蛇是否碰到自己 
int check_food(void);                        //检测蛇是否吃到食物 
void snake_add(char move);                //增加蛇的长度 
void game_over();                                //游戏结束,释放链表 

void game_over()                                //游戏结束,释放链表 
{
                Snake *temp;
                
                while(HEAD != NULL)
                {
                                temp = HEAD->next; 
                                free(HEAD);
                                HEAD = temp; 
                }
}

void snake_add(char move)                //增加蛇的长度 
{
                Snake *new;
                
                new = (Snake *) malloc(sizeof(Snake));
                
                if (new == NULL)
                {
                                printf ("生成蛇失败!\n");
                                
                                exit(0);                                 
                }
                
                switch (move)
                {
                                case 'w':
                                        new->x = TAIL->x +1;
                                        new->y = TAIL->y ;
                                        
                                        break;
                                        
                                case 'a':
                                        new->y = TAIL->y +1;
                                        new->x = TAIL->x;
                                        
                                        break;
                                        
                                case 's':
                                        new->x = TAIL->x -1;
                                        new->y = TAIL->y;
                                        
                                        break;
                                        
                                case 'd':
                                        new->y = TAIL->y -1;
                                        new->x = TAIL->x;
                                        
                                        break;
                }
                
                TAIL->next = new;
                new->next = new;
                TAIL = new; 
}

int check_food(void)                //检测蛇是否吃到食物 
{
                if (FOOD_MAP[HEAD->x][HEAD->y] == FOOD)
                {
                                FOOD_MAP[HEAD->x][HEAD->y] = ' ';
                                
                                return 1;
                }
                
                return 0;                        
}

int check_kill(void)                //检测蛇是否碰到自己 
{
                Snake *temp;
                
                temp = HEAD->next;
                
                while (temp != NULL)
                {
                                if (HEAD->x == temp->x && HEAD->y == temp->y)
                                {
                                                return 0;
                                }
                                
                                temp = temp->next;
                }
                
                return 1;
}

int check_cross(void)                //检测蛇是否越界 
{
                if (HEAD->x == 0 || HEAD->x == MAX -1 || HEAD->y == 0 || HEAD->y == MAX -1)
                {
                                return 0;
                }
                
                return 1;
}

int do_move (char move)                //判断蛇的移动 
{
                int tempxy[COUNT][2];
                int i = 0;
                Snake * temp;
                
                memset (tempxy, '0' , COUNT * 2 );
                
                if (move == 'w' || move == 'a' || move == 's' || move == 'd') 
                {
                                temp = HEAD;
                                
                                while (temp != NULL)
                                {
                                                tempxy[i][0] = temp->x;
                                                tempxy[i][1] = temp->y;
                                                
                                                i++;
                                                
                                                temp = temp -> next ; 
                                }
                                
                                i = 0;
                                
                                temp = HEAD -> next;
                                
                                while (temp != NULL)
                                {
                                                temp -> x = tempxy[i][0];
                                                temp -> y = tempxy[i][1];
                                                
                                                i++;
                                                
                                                temp = temp -> next;
                                }
                                
                                temp = HEAD;
                                
                                switch(move)
                                {
                                                case 'w':
                                                        HEAD->x = tempxy[0][0] - 1;
                                                        
                                                        break;
                                                        
                                                case 'a':
                                                        HEAD->y = tempxy[0][1] - 1;
                                                        
                                                        break;
                                                        
                                                case 's':
                                                        HEAD->x = tempxy[0][0] + 1;
                                                        
                                                        break;
                                                        
                                                case 'd':
                                                        HEAD->y        = tempxy[0][1] + 1;
                                                        
                                                        break;                                                
                                }
                                
                                if (!check_cross())
                                {
                                                return 0;
                                }
                                
                                if (!check_kill())
                                {
                                                return 0;
                                }
                                
                                if (!check_food())
                                {
                                                COUNT++;
                                                
                                                snake_add(move);
                                }
                }
                else if (move == 'q')
                {
                                return 0;
                }
                
                return 1;
}

void print_all(void)                //打印所有物品 
{
                static int count = 0;
                
                printf ("当前得分:%d\n", COUNT);
                
                if (COUNT - count == 4)
                {
                                FOOD_MAP_set_up();
                                
                                count = COUNT;
                }
                
                reset_MAP();
                put_snake();
                
                int i;
                for(i = 0; i < MAX; i++)
                {
                                int j;
                                for (j = 0; j < MAX; j++)
                                {
                                                if (FOOD_MAP[i][j] != ' ')
                                                {
                                                                printf ("%c", FOOD_MAP[i][j]);
                                                }
                                                else printf ("%c", MAP[i][j]);
                                }
                                
                                putchar('\n');
                 } 
}

void reset_MAP(void)                //刷新地图 
{
                int i;
                for (i =1; i < MAX -1; i++)
                {
                                int j;
                                for (j =1; j < MAX -1; j++)
                                {
                                                MAP[i][j] = ' ';
                                }
                }
}

void put_snake(void)                //将蛇放置在地图中 
{
                Snake * temp;
                
                temp = HEAD -> next;
                
                MAP[HEAD->x][HEAD->y] = 'c';
                
                while (temp != NULL)
                {
                                MAP[temp->x][temp->y] = SNAKE;
                                
                                temp = temp->next;
                }
}

void snake_set_up(void)                //生成蛇 
{
                HEAD = (Snake *) malloc (sizeof(Snake));
                
                if (HEAD == NULL)
                {
                                printf ("生成蛇失败!\n");
                                
                                exit(0); 
                }
                
                srand (time(NULL) +1);
                
                do
                {
                                HEAD->x = rand()%MAX;
                                HEAD->y = rand()%MAX;
                }
                
                while (HEAD->x == 0 || HEAD->x == MAX -1 || HEAD->y == 0 || HEAD->y == MAX -1);
                
                HEAD-> next = NULL;
                TAIL = HEAD;
}

void FOOD_MAP_set_up(void)                //生成食物地图 
{
                int i = 0, x, y;
                
                memset (FOOD_MAP, ' ', MAX * MAX);
                
                srand (time (NULL));
                
                do
                {
                                i++;
                                
                                do
                                {
                                                x = rand()%MAX;
                                                y = rand()%MAX;
                                }
                                while (x == 0 || x == MAX -1 || y == 0 || y == MAX -1);
                                
                                FOOD_MAP[x][y] = FOOD;
                }
                while(i!=4);
 } 

void MAP_set_up(void)                //生成地图 
{
                memset (MAP, ' ', MAX * MAX);
                
                int i;
                for (i = 0; i < MAX; i++)
                {
                                int j;
                                for (j = 0; j < MAX; j++)
                                {        
                                                if (i == 0 || j == 0 || i == MAX -1 || j == MAX -1)
                                                {
                                                                MAP[i][j] = '0';                                                
                                                }
                                                else MAP[i][j] = ' ';
                                }
                }                
}

void prinmain (void)                //打印主菜单 
{
                printf("1.开始游戏\n");
                printf("2.结束游戏\n");
                printf(":");
}

int main(void)
{
                char move;
                
                prinmain();
                scanf("%c",&move);
                getchar();
                
                if(move == '1')
                {
                                MAP_set_up();
                                FOOD_MAP_set_up();
                                snake_set_up();
                                
                                do
                                {
                                                system("clear");
                                                print_all();
                                                
                                                printf("请输入指令(w/a/s/d/q):");
                                                
                                                system("stty raw -echo");
                                                
                                                scanf("%c", &move);
                                                
                                                system("stty cooked echo"); 
                                }
                                while(do_move(move));
                }
                
                printf("\n游戏结束\n"); 
                
                system("stty cooked echo");
                
                game_over();
                
                return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-7 19:05:13 From FishC Mobile | 显示全部楼层
碧水青鱼 发表于 2020-3-7 18:47
代码抄完之后,排了下错,就成了下面这样了,但为什么我抄的代码不能玩呢?

你是用的编译器还是在Linux下运行的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-7 19:07:03 From FishC Mobile | 显示全部楼层
就是要努力呀 发表于 2020-3-7 19:05
你是用的编译器还是在Linux下运行的

我是在Linux里写的如果是编译器的话你应该要自己申请一个窗口 然后把system("clear")用gotoxy代替 还有另外system删除掉
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-7 19:09:41 From FishC Mobile | 显示全部楼层
就是要努力呀 发表于 2020-3-7 19:07
我是在Linux里写的如果是编译器的话你应该要自己申请一个窗口 然后把system("clear")用gotoxy代替 还有另 ...

我也不知道编译器可不可以用system
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-7 19:19:25 | 显示全部楼层
碧水青鱼 发表于 2020-3-7 18:47
代码抄完之后,排了下错,就成了下面这样了,但为什么我抄的代码不能玩呢?

你可以把错误信息贴出来看一下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-7 20:44:24 | 显示全部楼层
本帖最后由 碧水青鱼 于 2020-3-7 20:46 编辑
就是要努力呀 发表于 2020-3-7 19:19
你可以把错误信息贴出来看一下


不是说你的代码不好,是我自己抄得有问题,很多标点符号,大小写什么的抄错了,我说的排错是主要排这个错。另外有个问题是代码编译到
for(int ...)
这个地方就运行不下去,我百度查了一下,好像说int不能放在括号里面,要写成
int i;
for (i = 0; i < MAX; i++)
这样的格式才行,然后我照着改了,确实就可以往下编译了

然后,这代码抄完之后,虽然可以运行,但好像玩不了游戏,不知道怎么回事
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-7 20:49:39 | 显示全部楼层
就是要努力呀 发表于 2020-3-7 19:05
你是用的编译器还是在Linux下运行的

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

使用道具 举报

 楼主| 发表于 2020-3-7 21:23:23 From FishC Mobile | 显示全部楼层
没有报错没有警告就是对的呀
你看你键盘是不是开的大写
我偷懒没有写大写
只有小写才行
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-8 01:34:26 | 显示全部楼层
就是要努力呀 发表于 2020-3-7 21:23
没有报错没有警告就是对的呀
你看你键盘是不是开的大写
我偷懒没有写大写


添加大写很容易的
        switch(move)
        {
                case 'w':
                case 'W':
                        HEAD->x = tempxy[0][0] - 1;
                        break;
                case 'a':
                case 'A':
                        HEAD->y = tempxy[0][1] - 1;
                        break;
                case 's':
                case 'S':
                        HEAD->x = tempxy[0][0] + 1;
                        break;
                case 'd':
                case 'D':
                        HEAD->y = tempxy[0][1] + 1;
                        break;
        }
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-3-8 10:40:20 From FishC Mobile | 显示全部楼层
人造人 发表于 2020-3-8 01:34
添加大写很容易的

我就是赶个懒没有写这个贪吃蛇我写了10个小时
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-1-16 00:02

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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