C语言实战系列一:经典贪食蛇

C语言学习必须实战,并且学完语法后就必须立即用实战来巩固。一般需要10来个比较复杂的程序才能掌握C语言。今天就教大家第一个小程序,贪食蛇。

首先上代码

一、代码

#include <stdio.h>
#include <stdlib.h>
#include <curses.h>
#include <unistd.h>
#include <time.h>#define WIDTH 20
#define HEIGHT 10int score = 0;
int gameover;
int x, y, fruitX, fruitY, flag;int tailX[100], tailY[100];
int nTail;void setup() {gameover = 0;// 初始化蛇的位置x = WIDTH / 2;y = HEIGHT / 2;// 初始化食物的位置fruitX = rand() % WIDTH;fruitY = rand() % HEIGHT;
}void draw() {clear(); // 清屏for (int i = 0; i < WIDTH + 2; i++)printw("#");printw("\n");for (int i = 0; i < HEIGHT; i++) {for (int j = 0; j < WIDTH; j++) {if (j == 0)printw("#"); // 左墙if (i == y && j == x)printw("O"); // 蛇头else if (i == fruitY && j == fruitX)printw("F"); // 食物else {int isTail = 0;for (int k = 0; k < nTail; k++) {if (tailX[k] == j && tailY[k] == i) {printw("o"); // 蛇身isTail = 1;}}if (!isTail)printw(" ");}if (j == WIDTH - 1)printw("#"); // 右墙}printw("\n");}for (int i = 0; i < WIDTH + 2; i++)printw("#");printw("\n");printw("Score:%d", score);refresh(); // 刷新屏幕
}void input() {int ch = getch(); // 获取键盘输入switch (ch) {case 'a':flag = 1;break;case 'd':flag = 2;break;case 'w':flag = 3;break;case 's':flag = 4;break;case 'x':gameover = 1;break;}
}void algorithm() {usleep(100000); // 休眠,控制蛇的速度int prevX = tailX[0];int prevY = tailY[0];int prev2X, prev2Y;tailX[0] = x;tailY[0] = y;for (int i = 1; i < nTail; i++) {prev2X = tailX[i];prev2Y = tailY[i];tailX[i] = prevX;tailY[i] = prevY;prevX = prev2X;prevY = prev2Y;}switch (flag) {case 1:x--;break;case 2:x++;break;case 3:y--;break;case 4:y++;break;default:break;}// 判断是否碰到墙if (x < 0 || x >= WIDTH || y < 0 || y >= HEIGHT)gameover = 1;// 判断是否吃到食物if (x == fruitX && y == fruitY) {score += 10;fruitX = rand() % WIDTH;fruitY = rand() % HEIGHT;nTail++;}
}int main() {srand(time(NULL)); // 设置随机数种子initscr(); // 初始化 curseskeypad(stdscr, TRUE); // 启用键盘输入nodelay(stdscr, TRUE); // 非阻塞输入noecho(); // 关闭回显setup();while (!gameover) {draw();input();algorithm();}endwin(); // 关闭 cursesreturn 0;
}

二、编译

代码的运行平台是ubuntu,代码用到了curses库,需要提前安装:

 sudo apt-get install libncurses5-dev

然后用下面命令编译

gcc snake_game.c -o snake_game -lncurses

执行程序:

./snake_game

注意!如果速度过快,就会结束,直接跳出程序到控制台,如何修改速度下面会讲到。

三、编程指导

  1. 初始化 (setup 函数):

    • gameover: 游戏结束标志。
    • xy: 蛇头的初始坐标。
    • fruitXfruitY: 食物的初始坐标。
    • flag: 用于存储用户输入的方向。
    • score: 记录游戏得分。
    • nTail: 蛇身的长度。
    • tailXtailY: 用于存储蛇身各部分的坐标。
  2. 游戏主循环:

    while (!gameover) {draw();input();algorithm();
    }
    

    游戏在一个无限循环中进行,直到 gameover 变为真。在每次循环中,先绘制游戏画面,然后处理用户输入,最后执行游戏逻辑。

  3. 输入处理 (input 函数):

    • 使用 getch 函数获取键盘输入。
    • 根据用户输入的键值设置 flag 的值,表示蛇移动的方向。
    • 'a': 左,'d': 右,'w': 上,'s': 下,'x': 退出游戏。
  4. 游戏逻辑 (algorithm 函数):

    • 使用 usleep 函数添加一点延迟,以控制蛇的速度。(如果速度过快,游戏会很快结束,需要添加延时)
    • 更新蛇身的位置。
    • 根据用户输入的方向移动蛇头。
    • 判断是否碰到墙,如果是则游戏结束。
    • 判断是否吃到食物,如果是则增加得分,重新生成食物,增加蛇身的长度。
  5. 绘制 (draw 函数):

    • 使用 clear 函数清空屏幕。
    • 使用 printw 函数输出字符。
    • 使用 refresh 函数刷新屏幕。
    • 输出游戏画面,包括墙、蛇头、食物和蛇身。
    • 输出得分信息。
  6. 初始化和关闭 curses (initscrendwin 函数):

    • initscr: 初始化 curses 库。
    • keypad: 启用键盘输入。
    • nodelay: 设置非阻塞输入。
    • noecho: 关闭回显。
    • endwin: 关闭 curses 库。
  7. 编译和运行:

    • 使用 gcc 编译器编译程序,并链接 ncurses 库。
    • 运行生成的可执行文件。

四、继续完善

这段贪食蛇游戏代码已经基本完成了一个简单的实现,但仍然有一些方面可以改进和完善,具体包括:

  1. 边界检查:

    当蛇头移动到边界时,游戏会结束。可以考虑在边界处实现蛇穿越的效果,即从一侧穿越到另一侧。
  2. 游戏难度递增:

    目前游戏的难度保持不变,可以考虑逐渐增加蛇的移动速度或者加快食物的生成速度,使得游戏更具挑战性。
  3. 碰撞检测:

    目前只有边界碰撞检测和食物碰撞检测,可以考虑添加对蛇头与蛇身碰撞的检测,以防止游戏结束。
  4. 游戏结束提示:

    当游戏结束时,可以输出更友好的提示信息,告诉玩家是因为碰到墙还是碰到自己身体而导致游戏结束。
  5. 代码结构和模块化:

    将代码进一步模块化,使得各部分功能更清晰、易读、易于维护。可以考虑将一些功能性代码抽象成函数。
  6. 用户界面交互:

    添加开始界面和游戏结束后的界面,以提供更良好的用户体验。
  7. 更多游戏元素:

    考虑添加更多的游戏元素,如障碍物、特殊道具等,以增加游戏的趣味性和多样性。

这些功能给大家作为练习去实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/421662.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

代码随想录 Leetcode239. 滑动窗口最大值

题目&#xff1a; 代码&#xff08;首刷看解析 2024年1月22日&#xff09;&#xff1a; class Solution { private:class MyQueue{public:deque<int> que;void pop(int val){if (!que.empty() && que.front() val) {que.pop_front();}}void push(int val){whil…

C语言总结十三:程序环境和预处理详细总结

了解程序的运行环境可以让我们更加清楚的程序的底层运行的每一个步骤和过程&#xff0c;做到心中有数&#xff0c;预处理阶段是在预编译阶段完成&#xff0c;掌握常用的预处理命令语法&#xff0c;可以让我们正确的使用预处理命令&#xff0c;从而提高代码的开发能力和阅读别人…

亚热带常见病虫害识别系统的系统总体设计

文章目录 系统需求分析系统结构设计系统功能 系统需求分析系统时序图系统活动图 系统数据库设计数据库概念设计数据库逻辑设计数据库物理设计 小结 系统需求分析 系统结构设计 系统功能 &#xff08;1&#xff09;登录/注册 用户可以登陆系统,在已经登录过的情况下,可以输入邮…

BL121ML OPC UA网关实现Modbus、楼宇自控、电力协议转OPC UA

随着物联网技术的迅猛发展&#xff0c;人们深刻认识到在智能化生产和生活中&#xff0c;实时、可靠、安全的数据传输至关重要。在此背景下&#xff0c;高性能的物联网数据传输解决方案——协议转换网关应运而生&#xff0c;广泛应用于工业自动化和数字化工厂应用环境中。 钡铼…

linux杀毒软件clamav安装使用

1、下载 在下面地址下载&#xff1a;https://www.clamav.net/downloads 2、安装 clamav-1.2.1.linux.x86_64.rpm放在/home路径。 执行&#xff1a; chmod -R 777 /home/clamav-1.2.1.linux.x86_64.rpm rpm -ivh clamav-1.2.1.linux.x86_64.rpm3、下载病毒库 下载路径&am…

【论文解读】PV-RCNN: Point-Voxel Feature Set Abstraction for 3D Object Detection

PV-RCNN 摘要引言方法3D Voxel CNN for Efficient Feature Encoding and Proposal GenerationVoxel-to-keypoint Scene Encoding via Voxel Set AbstractionKeypoint-to-grid RoI Feature Abstraction for Proposal Refinement 实验结论 摘要 我们提出了一种新的高性能3D对象检…

100天精通Python(实用脚本篇)——第113天:基于Tesseract-OCR实现OCR图片文字识别实战

文章目录 专栏导读1. OCR技术介绍2. 模块介绍3. 模块安装4. 代码实战4.1 英文图片测试4.2 数字图片测试4.3 中文图片识别 书籍分享 专栏导读 &#x1f525;&#x1f525;本文已收录于《100天精通Python从入门到就业》&#xff1a;本专栏专门针对零基础和需要进阶提升的同学所准…

Axios取消请求:AbortController

AbortController AbortController() 构造函数创建了一个新的 AbortController 实例。MDN官网给出了一个利用AbortController取消下载视频的例子。 核心逻辑是&#xff1a;利用AbortController接口的只读属性signal标记fetch请求&#xff1b;然后在需要取消请求的时候&#xff0…

10.编写Shell脚本(1)

1.shell的组成 脚本声明 #!/bin/bash脚本注释 以#开头脚本命令 实现脚本的功能 2.分类 交互式(Interactive):用户每输入一条命令就立即执行。 批处理(Batch):由用户事先编写好一个完整的Shell脚本&#xff0c;Shel会一次性执行脚本中诸多的命令 shel…

HarmonyOS开源软件Notice收集策略说明

开源软件Notice是与项目开源相关的文件&#xff0c;收集这些文件的目的是为了符合开源的规范。 收集目标 只收集打包到镜像里面的模块对应的License&#xff1b;不打包的都不收集&#xff0c;比如构建过程使用的工具&#xff08;如clang、python、ninja等&#xff09;都是不收…

第91讲:MySQL主从复制集群主库与从库状态信息的含义

文章目录 1.主从复制集群正常状态信息2.从库状态信息中重要参数的含义 1.主从复制集群正常状态信息 通过以下命令查看主库的状态信息。 mysql> show processlist;在主库中查询当前数据库中的进程&#xff0c;看到Master has sent all binlog to slave; waiting for more u…

侧面车窗透明屏显示方案

侧面车窗透明屏显示方案是一种新型的汽车显示技术&#xff0c;其基本原理是在汽车侧窗玻璃上投射显示内容&#xff0c;从而在不影响驾驶员视线的情况下&#xff0c;提供额外的信息和娱乐。 该方案通常采用柔性OLED显示技术&#xff0c;因为柔性OLED具有轻薄、可弯曲的特性&…