贪吃蛇小游戏——C语言编写

article/2025/10/27 6:41:56

文章目录

  • 1.效果展示
  • 2.设计思路
    • 2.1图案显示
    • 2.2蛇头的移动
    • 2.3食物的生成
    • 2.4蛇身体的生成与移动
    • 2.5判断是否撞墙和打印得分
  • 3.完整代码

1.效果展示

在这里插入图片描述

2.设计思路

2.1图案显示

利用二维数组构建图案,总共有墙壁,蛇头,蛇身,食物,空白五种元素,因此只需要二维数组中的元素有五种不同的值即可;
在这里插入图片描述

在这里插入图片描述

2.2蛇头的移动

贪吃蛇是会自动移动的,我们首先让蛇头能自动移动。由于我们用数组来表示元素在地图中的位置,让元素移动就是让元素的坐标改变。
因此我们需要构建函数来完成蛇头坐标的自动移动,同时需要对我们输入的方向键做出判断,改变移动的方向。
在这里插入图片描述

2.3食物的生成

食物的生成很简单,只要种下一个随机数种子,然后给一个变量用来判断是否生成食物即可,需要注意的是食物的坐标别越界
在这里插入图片描述

2.4蛇身体的生成与移动

蛇身体的计算:
首先,蛇身体的移动前必须产生身体即是否吃到食物,可以给一个变量当计数器来判断有多少截身体;

蛇身体坐标的保存:
我们需要一个结构体数组,结构体数组的每个元素有两个成员x和y值,这两个值就代表我们的身体在二维数组中的坐标,
即一个数组成员就代表一截身体;

蛇身体坐标的获得:
通过计数器来判断是否有身体,当计数器不为0时,蛇就有了身体,第一截身体的坐标来源就是蛇头吃到食物前的坐标;
同理,后面吃到的食物增加,计数器的数值变大,就代表我们的结构体数组有多少个有效元素,然后给结构体数组里面的成员进行赋值;
最后一截身体的数组下标=计数器-1,后面的身体坐标就是前面的身体移动前的坐标,由于我们的头是不断移动的,并且可以直接获得其坐标,所以从最后一截身体开始往前进行拷贝赋值;
由于我们的赋值特点,数组(蛇身)从后往前进行覆盖式拷贝赋值,即完成了蛇身体的移动

没有吃到食物时的细节:
没有吃到食物时,蛇的身体长度是不变的,我们的身体坐标进行改变之后,在二维数组中留下了一个隐患;
在这里插入图片描述
在这里插入图片描述

2.5判断是否撞墙和打印得分

打印得分:得分即身体的长度即计数器的数值

判断是否撞墙:判断蛇头的下一个位置在二维数组中是不是1即是不是墙壁即可
在这里插入图片描述

3.完整代码

#ifndef _SNAKE_H_
#define _SNAKE_H_#include <stdio.h>
#include <windows.h>
#include <time.h>
#include <stdlib.h>
#include <conio.h>#define MAX 500 //蛇身个数
#define ROW 20  
#define LINE 20typedef struct Body
{int x;int y;
}body;void MapPrint(char arr[][LINE], int count);//地图打印void Move(int *row, int *line, char *move);//蛇头移动函数,通过读取输入的键盘方向键来改变蛇头方向void GetCoordinate(int *row, int *line, char *move);//蛇头自动移动,通过获取的方向信息,决定蛇头往哪个方向自动移void food(char arr[][LINE], int *x, int *y);//随机生成一个食物void JudgeFood(int food_x, int food_y, int row, int line, int *count);//判断是否吃到食物void GetBody(char arr[][LINE], body body[], int count, int temp_x, int temp_y);//蛇体坐标更新int  Judge(char arr[][LINE], int row, int line);//判断是否撞墙void Game();#endif
#include "snake.h"void gotoxy(int x, int y)//将光标移动到(x,y)位置
{HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);COORD pos;pos.X = x;pos.Y = y;SetConsoleCursorPosition(handle, pos);}void MapPrint(char arr[][LINE],int count)
{	gotoxy(0, 0);for (int i = 0; i < ROW; i++){for (int j = 0; j < LINE; j++){//第一行,最后一行,第一列,最后一列都是墙壁if (arr[i][j]==1)printf("■");else if (arr[i][j] == 2)printf("⊙");//蛇头else if (arr[i][j] == 3)printf("¤");//打印食物¤else if (arr[i][j] == 4)printf("●");//打印身体●elseprintf("  ");//一个墙体占两个空格}printf("\n");}printf("				\n");printf("             当前得分:%d\n", count);printf("				\n");
}
void Move(int *row, int *line,char *move)//蛇头移动函数,通过读取输入的键盘方向键来改变蛇头方向
{if (GetAsyncKeyState(VK_UP))//上{*move = 'w';}else if (GetAsyncKeyState(VK_DOWN))//下{*move = 's';}else if (GetAsyncKeyState(VK_LEFT))//左{*move = 'a';}else if (GetAsyncKeyState(VK_RIGHT))//右{*move = 'd';}GetCoordinate(row, line, move);//将获得的方向键信息传输过去
}void GetCoordinate(int *row, int *line, char *move)//蛇头自动移动,通过获取的方向信息,决定蛇头往哪个方向自动移
{if (*move == 'w')(*row)--;else if (*move == 's')(*row)++;else if (*move == 'a')(*line)--;else if (*move == 'd')(*line)++;
}void food(char arr[][LINE],int *x,int *y)//随机生成一个食物
{int flag = 0;for (int i = 0; i < ROW; i++){for (int j = 0; j < ROW; j++){if (arr[i][j] == 3)//食物为3flag = 1;}}if (!flag)//没有食物就生成食物{//食物不能在边框上*x = rand() % (ROW-2)+1;*y = rand() % (LINE-2)+1;}
}void JudgeFood(int food_x,int food_y,int row,int line,int *count)//判断是否吃到食物
{if (food_x == row&&food_y == line)//吃到食物{(*count)++;//吃到食物身体个数+1}
}void GetBody(char arr[][LINE], body body[], int count, int temp_x, int temp_y)//蛇体坐标更新
{//保留前一个蛇体的坐标int befor_x = 0;int befor_y = 0;if (count > 0)//最少有一个蛇身{//记录下最后一个蛇身的位置befor_x = body[count - 1].x;befor_y = body[count - 1].y;}int keep = count;//保存一份蛇体个数while (count)//蛇体坐标覆盖,后面的覆盖前面的{if (count == 1)//只有一个蛇体时,为原来蛇头位置{body[count - 1].x = temp_x;body[count - 1].y = temp_y;}else{body[count - 1].x = body[count - 2].x;body[count - 1].y = body[count - 2].y;}count--;}while (keep)//将对应的蛇体坐标赋值{arr[body[keep-1].x][body[keep-1].y] = 4;keep--;}if (befor_x!=0)//最后一个蛇身的上一次所在位置清空{arr[befor_x][befor_y] = 0;}}int  Judge(char arr[][LINE],int row,int line)//判断是否撞墙
{if (arr[row][line] == 1){printf("	 --------------\n");printf("	|   撞到墙壁   |\n");printf("	|   游戏结束   |\n");printf("	 --------------\n");system("pause");return 0;}return 1;
}void Game()
{char arr[ROW][LINE]={{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ,1 },{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },};//地图int row = 10, line = 10;//蛇头起始位置arr[row][10] = 2;char move = 'w';//蛇头开始往上移动int food_x = 0, food_y = 0;//食物的x,y坐标srand((unsigned)time(NULL));//随机数种子//保留一份蛇头移动前坐标int temp_x = row;int temp_y = line;int count = 0;//蛇身体个数body body[MAX] = { 0 };//蛇身坐标记录结构体数组while (1){	//生成食物food(arr, &food_x, &food_y);arr[food_x][food_y] = 3;MapPrint(arr,count);//打印图形if (count==0)arr[row][line] = 0;//没有身体的时候,蛇头原来位置变为空白//保留蛇头移动前的位置temp_x = row;temp_y = line;Move(&row, &line,&move);//蛇头移动if (Judge(arr, line, row) == 0)//判断是否撞墙{break;}JudgeFood(food_x,food_y,row, line, &count);//判断是否吃到食物GetBody(arr, body, count, temp_x, temp_y);//蛇身构造arr[row][line] = 2;//新位置变成蛇头Sleep(200);//通过控制休眠时间来控制蛇头移动速度}
}
#include "snake.h"int main()
{Game();printf("游戏结束\n");system("pause");return 0;
}

http://chatgpt.dhexx.cn/article/PmDdANUU.shtml

相关文章

用C语言编写贪吃蛇小游戏

实现功能 蛇最开始三节&#xff0c;向右移动。用户可以通过按上下左右来控制蛇的移动&#xff0c;食物随机产生&#xff0c;蛇吃到食物后蛇的身体会变长。蛇撞墙或者撞到自己身体后&#xff0c;游戏结束。 怎么实现 要实现一个贪吃蛇小游戏&#xff0c;首先要想清楚游戏里有…

用C语言编写2048游戏

2048_C_code 用C语言编写的2048 1 要实现我们的 2048 小游戏&#xff0c;需要涉及一些数据结构的知识&#xff0c;以及一些 Linux 的系统调用。此外&#xff0c;为了方便在屏幕上使用字符绘图&#xff0c;我们还需要使用一个文本界面的屏幕绘图库 ncurses &#xff0c;具体到…

C语言编写猜数字小游戏

C语言编写猜数字小游戏 经过对C语言的初步学习&#xff0c;为提高编程能力&#xff0c;可以敲一些稍费脑筋的代码&#xff0c;猜数字就是一个很好的选择。要想实现该游戏&#xff0c;那么首先我们应该知道制作的大体思路。 电脑应随机产生一个数字&#xff08;为便于玩家猜的…

C语言编写2048小游戏

一、原理 这里以向上移动为例&#xff0c;其他方向的移动类似。 因为纵向移动不会横向变化&#xff0c;所以可以单独拿出某一列来分析。 我们先假设一个具有代表性的例子&#xff0c;假设当前某列数据是【2】【0】【2】【8】&#xff08;0代表空白&#xff09;&#xff0c;如…

Linux C语言编写2048小游戏

2048 2048小游戏是用Linux C语言写的&#xff0c;运行在Ubuntu系统上&#xff0c;其中Ubuntu链接Ncuses库。首先&#xff0c;我们简单了解一下Ncurses。 Ncurses库是由原CURSES库发展而来的&#xff0c;这个库提供了C/C对屏幕以及光标、鼠标访问的特性。使得C/C简易写屏成为可能…

C语言编写小游戏:MinesWeeper(扫雷)闯关版

《扫雷》&#xff1a;大众类的益智小游戏&#xff0c;游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子&#xff0c;同时避免踩雷&#xff0c;踩到一个雷即全盘皆输。 话不多说&#xff0c;我们直接进入正题。 首先&#xff0c;我们得给用户显示一个菜单栏&…

(C语言)用C语言编写小游戏——三子棋

目录 三子棋效果展示 三子棋的功能实现 1、初始化棋盘格 2、打印棋盘 3、玩家下棋 4、电脑下棋 5、判断输赢&#xff08;玩家赢/电脑赢/平局&#xff09; 完整代码展示 三子棋小游戏的代码实现分为三个文件&#xff0c;test.c&#xff08;测试游戏功能&#xff09;、ga…

c语言编写的小游戏(c语言编写小游戏入门)

C语言编写是要注意什么&#xff1f; 因此&#xff0c;在编写选择语句之前&#xff0c;应该首先明确判断条件是什么&#xff0c;并确定当判断结果为“真”或“假”时应分别执行什么样的操作(算法) c语言编写小游戏请提供俄罗斯方块&#xff0c;坦克大战之类的小游戏的程序的c 应…

(C语言)用C语言编写小游戏——扫雷

目录 扫雷效果展示 扫雷的功能实现 1、初始化棋盘格 2、 打印棋盘 3、布置雷 4、排查雷 完整代码展示 扫雷小游戏的代码实现分为三个文件&#xff0c;test.c&#xff08;测试游戏功能&#xff09;、game.h&#xff08;头文件的包含和函数的声明&#xff09;、game.c&…

详解5个C语言简单易懂小游戏

文章目录 前言一、准备工作二、游戏菜单三、游戏内容1.猜数字2.三子棋3.扫雷4.五子棋5.飞行棋 总结 前言 我们通过5个简单易懂的小游戏来加强我们对C语言的认识&#xff0c;这五个小游戏不仅有单人&#xff0c;还有人机对战和人人对战。让我们在学习之余来上一局紧张刺激的小游…

C语言趣味小游戏——扫雷(详解版)

前言 ​ 全篇无任何废话&#xff0c;本文的解释大多数都在代码段中&#xff0c;所以一定要看代码&#xff0c;边看边学边理解。 这只是初学者入门的一个小游戏&#xff0c;不难懂&#xff0c;没有什么复杂的内容 可以先学习一下比扫雷还简单的猜数字和三子棋 C语言趣味小游戏—…

C语言小程序游戏

c语言小程序游戏 ​ 本代码是我大一刚学完c语言自己编写的&#xff0c;三个游戏分别是飞机竞速、走迷宫和魔塔&#xff0c;满满的都是回忆。 1、不可能的任务-飞机竞速 ​ 这种游戏在以前小时候玩的游戏机里面玩过&#xff0c;那时抱着个游戏机一玩就是一下午&#xff0c;如…

C语言简易小游戏

文章目录 前言一、猜数字游戏二、旋转光标三、多个字符从两端移动&#xff0c;向中间汇聚四、恶搞&#xff1a;关机小程序五、闪烁的五彩爱心六、扫雷七、三子棋 前言 本篇博客将带领大家自己动手写一下一些C语言小游戏&#xff1b;以增加对于C语言的兴趣&#x1f600;&#x…

c语言成绩管理系统(链表)

C语言实现了学生成绩管理系统&#xff0c;可以进行学生成绩的增加&#xff0c;删除&#xff0c;修改&#xff0c;查询&#xff0c;计算平均成绩和展示。 开发语言&#xff1a;C语言 开发工具&#xff1a;Dev c 开发者&#xff1a;呵呵up 创建学生成绩信息 2. 插入学生信息 3.…

C语言实现学生成绩管理系统设计

本系统有增加学生记录、修改学生记录、删除学生记录、按姓名查询学生记录、按C语言成绩对学生进行排序、退出系统6大功能。 能够对学生的姓名&#xff0c;学号&#xff0c;c语言成绩做相应的操作。 在检测到输入成绩大于55时&#xff0c;会自动加上5。 该管理系统设计功能模块…

c语言成绩管理系统常见错误,求教 学生成绩管理系统出错

已结贴√ 问题点数:20 回复次数:5 求教 学生成绩管理系统出错 小弟刚做了个学生成绩管理系统 编译无错误 但是运行的时候连选择函数都不能 特来求教 望高手解释 代码如下: #include #include #define N 20 #define M 100 struct score {int scr1; int scr2; int scr…

c语言课程设计 学生成绩管理系统

学生成绩管理系统要求&#xff1a; 1、系统功能以菜单方式工作&#xff1b; 2、数据的输入&#xff1b; 3、数据的插入&#xff1b; 4、数据的输出&#xff1b; 5、数据的删除&#xff1b; 6、数据的查找&#xff0c;通常以两种方式进行查找&#xff0c;如姓名、学号&#xff1…

C语言学生成绩管理系统详解

文章目录 一、系统概述二、数据类型三、自定义函数说明四、运行界面五、源代码 源代码请直接跳到最后 引言&#xff1a;最近写了C语言的大作业&#xff0c;感觉做得还行&#xff0c;记录一下&#xff0c;给后人一些参考&#xff0c;给自己留更深印象方便后续改进&#xff01; …

学生成绩管理系统 C语言

基础篇问题&#xff1a; 1.输出如下菜单&#xff1a; *********************学生成绩管理系统******************* * 1 成绩录入 2 成绩查询 3 计算平均分 * * 4 计算最高分 5 排名 6 退出 * ******************************…

C语言编程学生成绩管理系统

目录 一、介绍 二、功能 1.录入学生 2.删除学生信息 3.修改学生信息 4.查询学生信息 5.所有学生信息 6.成绩排序 7.退出程序 三、代码 1.主函数 2.头文件 3.函数封装库 一、介绍 利用C语言&#xff0c;运用链表、指针、封装函数等基本知识实现一个学生管理系统。通…