C语言 —— 贪吃蛇

时间:2022-09-24 19:26:52

参考视频:https://www.bilibili.com/video/av29580072/?p=1

GreedySnake.h

 #ifndef GREEDYSNAKE_H_INCLUDED
#define GREEDYSNAKE_H_INCLUDED #define SNAKE_LENGTH 20 //蛇的长度最大为20
#define true 1
#define false 0
enum {UP = -, DOWN = , LEFT = -, RIGHT = }; typedef int bool; void FirstPage(); //设置起始游戏界面
void TestSpace(); //按空格开始游戏
void ShowBackground(); //展示游戏背景
void SetSnakeRandPos(); //为蛇产生一个随机的位置
void DrawSnake(); //画蛇
void SnakeMove(); //蛇动
void DestroySnake(); //销毁蛇
void ChangeDir(); //蛇随着方向键动起来
bool IsSnakeDie(); //判断蛇是否死亡
void ProduceFood(); //随机位置产生食物
void SnakeGrowUp(); //蛇变长
void PrintScore(); //打印分数 #endif // GREEDYSNAKE_H_INCLUDED

GreedySnake.c

 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <windows.h>
#include <time.h>
#include "GreedySnake.h" //把所有元素置为0
//snake[0][0]表示蛇头的行,snake[0][1]表示蛇头的列,snake[0][2]表示蛇头移动的方向
int g_arrSnake[SNAKE_LENGTH][] = { }; int g_iSnakeLength = ; //初始长度为3,但数组下标从0开始,故此处为2 char g_arrBackGround[][] =
{
"████████████████████████\n", //一个█占两个字节,占两个字符的位置
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"█ █\n",
"████████████████████████\n"
}; int g_iSnakeDir = LEFT; //蛇的方向,默认向左
bool g_bIsProFood = true; //蛇产生食物的标记
int g_iRow; //食物的行坐标
int g_iCol; //食物的列坐标 int g_iScore = ; //分数 void FirstPage() //设置起始游戏界面
{
for (int i = ; i < ; ++i)
printf(" ");
for (int i = ; i < ; ++i)
printf("*");
printf("\n"); for (int j = ; j < ; ++j)
{
for (int i = ; i < ; ++i)
printf(" ");
printf("*");
for (int i = ; i < ; ++i)
printf(" ");
printf("*\n");
} for (int i = ; i < ; ++i)
printf(" ");
printf("*");
for (int i = ; i < ; ++i)
printf(" ");
printf("《 欢迎来到贪吃蛇的世界!》");
for (int i = ; i < ; ++i)
printf(" ");
printf("*\n"); for (int i = ; i < ; ++i)
printf(" ");
printf("*");
for (int i = ; i < ; ++i)
printf(" ");
printf("《 请按空格键开始游戏 》");
for (int i = ; i < ; ++i)
printf(" ");
printf("*\n"); for (int j = ; j < ; ++j)
{
for (int i = ; i < ; ++i)
printf(" ");
printf("*");
for (int i = ; i < ; ++i)
printf(" ");
printf("*\n");
} for (int i = ; i < ; ++i)
printf(" ");
for (int i = ; i < ; ++i)
printf("*");
for (int i = ; i < ; ++i)
printf("\n");
} void TestSpace() //按空格开始游戏
{
char c;
while ((c = getch()) != ' ') //getch()在头文件<conio>内
{ }
system("cls"); //清屏
} void ShowBackground() //展示游戏背景
{
for (int i = ; i < ; ++i)
printf(g_arrBackGround[i]);
} void SetSnakeRandPos() //设置蛇的初始位置,默认蛇的身子为三节,向左移动
{
int x, y;
srand((unsigned)time(NULL));
x = rand()% + ; //因为蛇的身子起始为三节,所以x的范围为1-20(蛇不能起始就撞墙)
y = rand()% + ; g_arrSnake[][] = y; //行 注意:x,y和初始背景中的行列刚好是反的
g_arrSnake[][] = x * ; //列 注意:一个█占两个字节,所以算其坐标时要乘以2
g_arrSnake[][] = LEFT; //方向 g_arrSnake[][] = y;
g_arrSnake[][] = x * + ;
g_arrSnake[][] = LEFT; g_arrSnake[][] = y;
g_arrSnake[][] = x * + ;
g_arrSnake[][] = LEFT; DrawSnake();
} void DrawSnake() //展示蛇
{
//因为一个█占两个字节,所以不能直接用strcpy(&arrBackGround[arrSnake[i][0]][arrSnake[i][1]],"█");否则会把\0拷贝进来,导致出错
//由于前面把arrSnake的所有元素都置为了0,所以当arrSnake[i][0]为0时,代表那个坐标处没有蛇的身子
for (int i = ; g_arrSnake[i][] != ; ++i)
strncpy(&g_arrBackGround[g_arrSnake[i][]][g_arrSnake[i][]], "█", ); //注意取地址符&不能漏掉!
} void DestroySnake() //销毁蛇
{
for (int i = ; g_arrSnake[i][] != ; ++i)
strncpy(&g_arrBackGround[g_arrSnake[i][]][g_arrSnake[i][]], " ", ); //注意取地址符&不能漏掉! } void SnakeMove() //蛇动
{
DestroySnake();
for(int i = SNAKE_LENGTH - ; i >= ; --i)
{
if(g_arrSnake[i][] != )
{
//把前一个节点的值,赋给当前节点
g_arrSnake[i][] = g_arrSnake[i-][];
g_arrSnake[i][] = g_arrSnake[i-][];
g_arrSnake[i][] = g_arrSnake[i-][];
}
} g_arrSnake[][] = g_iSnakeDir; //设置蛇头方向 //处理第一个节点(蛇头)
if(g_arrSnake[][] == LEFT || g_arrSnake[][] == RIGHT) //左右移动,列加减2
{
g_arrSnake[][] += g_arrSnake[][];
}
else
{
g_arrSnake[][] += g_arrSnake[][]; //上下移动,行加减1
} DrawSnake(); } void ChangeDir() //改变方向
{
//不能用getchar(), 会回显,并且要按回车之后才会开始读取
//不能用getch(), 同步检测 //异步检测
if(GetAsyncKeyState('W'))
{
if (g_arrSnake[][] != DOWN) //蛇不能回头
g_iSnakeDir = UP;
} if(GetAsyncKeyState('S'))
{
if (g_arrSnake[][] != UP)
g_iSnakeDir = DOWN;
} if(GetAsyncKeyState('A'))
{
if (g_arrSnake[][] != RIGHT)
g_iSnakeDir = LEFT;
} if(GetAsyncKeyState('D'))
{
if (g_arrSnake[][] != LEFT)
g_iSnakeDir = RIGHT;
}
} bool IsSnakeDie() //蛇死亡判断(包括撞墙和吃自己,两种情况)
{
if(g_arrSnake[][] == LEFT || g_arrSnake[][] == RIGHT) //如果蛇左右移动,则判断蛇头的左右是否是"█",如果是,则判定为蛇死亡
{
if(!strncmp(&g_arrBackGround[g_arrSnake[][]][g_arrSnake[][]+g_arrSnake[][]], "█", )) //注意取地址符&不能漏掉!
return true;
}
else //如果蛇上下移动,则判断蛇头的上下是否是"█"
{
if(!strncmp(&g_arrBackGround[g_arrSnake[][]+g_arrSnake[][]][g_arrSnake[][]], "█", ))
return true;
}
return false;
} void ProduceFood() //随机位置产生食物
{
//判断是否产生新的食物
if(g_bIsProFood == false)
return; bool bFlag = true;
srand((unsigned)time(NULL)); while() //产生合法的食物,即食物不与蛇的身子重合
{
g_iRow = rand()% + ; //行
g_iCol = rand()% + ; for (int i = ; g_arrSnake[i][] != ; i++) //遍历蛇
if (g_iRow == g_arrSnake[i][] && g_iCol == g_arrSnake[i][]) //如果在食物产生在蛇身上
{
bFlag = false;
break;
} if(bFlag == true)
break;
} strncpy(&g_arrBackGround[g_iRow][g_iCol*], "★", );
g_bIsProFood = false;
} void SnakeGrowUp() //蛇变长
{
if(g_iRow == g_arrSnake[][] && g_iCol* == g_arrSnake[][]) //注意:列要乘以2
{
if (UP == g_arrSnake[g_iSnakeLength][])
{
g_arrSnake[g_iSnakeLength+][] = g_arrSnake[g_iSnakeLength][]+;
g_arrSnake[g_iSnakeLength+][] = g_arrSnake[g_iSnakeLength][];
g_arrSnake[g_iSnakeLength+][] = g_arrSnake[g_iSnakeLength][];
}
else if (DOWN == g_arrSnake[g_iSnakeLength][])
{
g_arrSnake[g_iSnakeLength+][] = g_arrSnake[g_iSnakeLength][]-;
g_arrSnake[g_iSnakeLength+][] = g_arrSnake[g_iSnakeLength][];
g_arrSnake[g_iSnakeLength+][] = g_arrSnake[g_iSnakeLength][];
}
else if (LEFT == g_arrSnake[g_iSnakeLength][])
{
g_arrSnake[g_iSnakeLength+][] = g_arrSnake[g_iSnakeLength][];
g_arrSnake[g_iSnakeLength+][] = g_arrSnake[g_iSnakeLength][]+;
g_arrSnake[g_iSnakeLength+][] = g_arrSnake[g_iSnakeLength][];
}
else if (RIGHT == g_arrSnake[g_iSnakeLength][])
{
g_arrSnake[g_iSnakeLength+][] = g_arrSnake[g_iSnakeLength][];
g_arrSnake[g_iSnakeLength+][] = g_arrSnake[g_iSnakeLength][]-;
g_arrSnake[g_iSnakeLength+][] = g_arrSnake[g_iSnakeLength][];
}
g_iSnakeLength++;
g_bIsProFood = true;
g_iScore++;
} } void PrintScore() //打印分数
{
COORD rd;
//设置光标位置
rd.X = ;
rd.Y = ;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), rd);
printf("分数"); rd.X = ;
rd.Y = ;
//设置光标位置
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), rd);
//打印
printf ("%d", g_iScore);
}

main.c

 #include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#include <time.h>
#include "GreedySnake.h" int main()
{
FirstPage();
TestSpace();
system("cls");
SetSnakeRandPos();
ShowBackground(); while ()
{
system("cls");
ProduceFood();
SnakeGrowUp();
ChangeDir(); if(IsSnakeDie())
{
printf("snake die!\n");
break;
} SnakeMove();
ShowBackground();
PrintScore(); Sleep();
}
system("pause");
return ;
}

C语言 —— 贪吃蛇的更多相关文章

  1. c语言贪吃蛇详解3&period;让蛇动起来

    c语言贪吃蛇详解3.让蛇动起来 前几天的实验室培训课后作业我布置了贪吃蛇,今天有时间就来写一下题解.我将分几步来教大家写一个贪吃蛇小游戏.由于大家c语言未学完,这个教程只涉及数组和函数等知识点. 上次 ...

  2. c语言贪吃蛇详解-2&period;画出蛇

    c语言贪吃蛇详解-2.画出蛇 前几天的实验室培训课后作业我布置了贪吃蛇,今天有时间就来写一下题解.我将分几步来教大家写一个贪吃蛇小游戏.由于大家c语言未学完,这个教程只涉及数组和函数等知识点. 蛇的身 ...

  3. c语言贪吃蛇详解1&period;画出地图

    c语言贪吃蛇详解-1.画出地图 前几天的实验室培训课后作业我布置了贪吃蛇,今天有时间就来写一下题解.我将分几步来教大家写一个贪吃蛇小游戏.由于大家c语言未学完,这个教程只涉及数组和函数等知识点. 首先 ...

  4. c语言贪吃蛇详解5&period;GameOver功能与显示成绩

    c语言贪吃蛇详解5.GameOver功能与显示成绩 以前我们已经做出来了一个能吃东西变长的蛇.不过它好像不会死... 现在就来实现一下game over的功能吧. 写个函数判断蛇是否撞到自己或者撞到墙 ...

  5. c语言贪吃蛇详解4&period;食物的投放与蛇的变长

    c语言贪吃蛇详解4.食物的投放与蛇的变长 前几天的实验室培训课后作业我布置了贪吃蛇,今天有时间就来写一下题解.我将分几步来教大家写一个贪吃蛇小游戏.由于大家c语言未学完,这个教程只涉及数组和函数等知识 ...

  6. 程序游戏推荐&lpar;C语言贪吃蛇,python天天酷跑&lpar;需要安装pygame&rpar;,js是狠人就坚持30s&rpar;

    下面是下载位置,我把他们上传到我的文件下了. C语言贪吃蛇:https://files.cnblogs.com/files/ITXiaoAng/%E8%B4%AA%E5%90%83%E8%9B%87. ...

  7. C&sol;C&plus;&plus;编程笔记:C语言贪吃蛇源代码控制台(二),分数和食物!

    接上文<C/C++编程笔记:C语言贪吃蛇源代码控制台(一),会动的那种哦!>如果你在学习C语言开发贪吃蛇的话,零基础建议从上一篇开始哦!接下来正式开始吧! 三.蛇的运动 上次我已经教大家画 ...

  8. C&sol;C&plus;&plus;编程笔记:C语言贪吃蛇源代码控制台(一),会动的那种哦!

    前几天有个同学加我QQ私聊我说他们老师布置了一个贪吃蛇,他不知道怎么写所以来找我求解,我给他简单讲解了思路和一些难点之后他也能够自己独立将项目完成了!考虑到更多同学可能有贪吃蛇上的问题,今天有时间就来 ...

  9. c语言贪吃蛇

    思路:函数gotoxy(x,y)使光标移植屏幕的x,y坐标(屏幕左上角为0,0),用来绘制蛇和界面,color()函数用来设置绘制的颜色.设有snakelong节,第i节蛇的x坐标为x[i],y坐标为 ...

  10. &lbrack;C语言&rsqb;贪吃蛇&lowbar;结构数组实现

    一.设计思路 蛇身本质上就是个结构数组,数组里存储了坐标x.y的值,再通过一个循环把它打印出来,蛇的移动则是不断地刷新重新打印.所以撞墙.咬到自己只是数组x.y值的简单比较. 二.用上的知识点 结构数 ...

随机推荐

  1. volley&lowbar;之2

    一开始会不会觉得有点怔,为什么只需要将请求添加到队列中,不需要去发送请求吗?当然是要的,只是这一切都被封装在Volley后面而已. 我们先来看一下隐藏在Volley后面的这个架构是怎么样的吧,如下图: ...

  2. Qt 框架 开发HTTP 服务器 开发记录

    最近需求需要开发一款 HTTP ,然后由于先前接触过Qt,就直接用Qt写HTTP服务器了,也是为了当作练手,要不然是直接上HTTP框架的. 后端用C++ Qt框架 前端为了练手 当然是纯生的 js h ...

  3. POJ2632Crashing Robots

    做模拟题做的我直接睡着了,题并不难,就是一个细心的问题,有一些细节问题注意了就差不多了,代码写的精美的一般找错误也好找一些,应该学着些好看的代码 #include<cstdio> #inc ...

  4. SCAU 07校赛 10317 Fans of Footbal Teams

    10317 Fans of Footbal Teams 时间限制:1000MS  内存限制:65535K 题型: 编程题   语言: 无限制 Description Two famous footba ...

  5. material-dialogs

    https://github.com/afollestad/material-dialogs

  6. 一维DFT

    学习DIP第3天 傅里叶变换是一个非常大的话题.今天实现了下一维的DFT,兴许将完毕其它傅里叶系的算法实现和实验. DFT公式:                             当中e 是自然 ...

  7. django email用法

    在settings里面设置 EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'EMAIL_PORT = 25EMAIL_HOST ...

  8. Jquery - 添加属性、添加class、添加Css

    一.设置属性: 方式一  jQuery 代码: $("img").attr({ src: "test.jpg", alt: "Test Image&q ...

  9. Vue 汇总

    1.右键菜单(防止默认行为) @contextmenu.native.prevent="rightClick()"

  10. &lbrack;&period;NET开发&rsqb; C&num; 如何创建Excel多级分组

    要设置显示或者隐藏分类数据下的详细信息,在便于数据查看.管理的同时也使文档更具美观性.那么,在C#中如何来创建Excel数据的多级分组显示呢?下面将进行详细阐述.方法中使用了免费版组件Free Spi ...