C++实现简单贪吃蛇游戏

文章目录

    • 1 开发历程
    • 2 开发思路
    • 3 使用介绍
    • 4 源文件代码
    • 5 游戏截图
    • 6 小结

1 开发历程

游戏使用C++语言开发,是博主某个下午心血来潮的结果,后面又花了点时间加了计分,记录历史得分的功能。

2 开发思路

其实贪吃蛇主要难在蛇身的移动上,想像着蛇移动的模样,不禁让人想起链表这种数据结构,蛇的头带动蛇身的第二节,第二节带动第三节,每一节的移动方向会遗传给下一节,把握住这一点,难点就迎刃而解了。

3 使用介绍

由于整个项目只有一个文件,使用g++ -o snake main.cpp命令编译源文件,就可以得到一个名为snakeexe可运行程序,接着在exe同目录下打开cmd使用下面两个命令来执行程序:

  • snake start,开始游戏,w、s、a、d四个按键(不分大小写)控制蛇的移动方向,若蛇碰到墙壁或者自身,则游戏结束,并将计分存入名为rank.txt的文件中。
  • snake rank,查看历史前五得分记录。

4 源文件代码

#include <iostream>
#include <cstring>
#include <fstream>
#include <set>
#include <windows.h>
#include <conio.h>
#include <time.h>
#define HEIGHT 15
#define WIDTH 35
#define INIT_FLUSHRATE 200
#define INIT_SCORE 0
#define BODY '@'
#define EMPTY ' '
#define FOOD '*'
#define EDGE '#'
#define RANKFILE "rank.txt"
using namespace std;
bool keyIsput = false;enum class Orient {UP, DOWN, LEFT, RIGHT};typedef struct node {int row;int col;Orient direction;struct node* next;
} Node;typedef struct {int frow;int fcol;
} Food;bool FoodInSnake(const int& r, const int& c, Node* q) {while (q != NULL) {if (q->row == r && q->col == c)return true;q = q->next;}return false;
}void printRank(){ifstream fin(RANKFILE);if(!fin){cerr << RANKFILE << " does not exit or open file error!!";exit(1);}if(fin.peek()==ifstream::traits_type::eof()){cout << "file is empty";exit(1);}for(int i=0; i<5; ++i){int tmp;if(fin.eof())break;fin >> tmp;cout << "No." << i+1 << ": " << tmp << '\n';}
}class Snake {
private:Node* snakeHead;public:static Orient tmp_1, tmp_2;Snake(int r, int c, Orient ori) {snakeHead = new Node;snakeHead->row = r;snakeHead->col = c;snakeHead->direction = ori;snakeHead->next = NULL;}Node* getHead() {return snakeHead;}void setOrient(Orient ori) {tmp_1 = snakeHead->direction;snakeHead->direction = ori;}void move() {Node* p = snakeHead;while (p != NULL) {if (p == snakeHead) {if(keyIsput==false)tmp_1 = p->direction;}else if (p != snakeHead) {tmp_2 = p->direction;p->direction = tmp_1;tmp_1 = tmp_2;}switch (p->direction) {case Orient::UP:(p->row)--; break;case Orient::DOWN:(p->row)++; break;case Orient::LEFT:(p->col)--; break;case Orient::RIGHT:(p->col)++; break;default:break;}p = p->next;}keyIsput = false;}void longer(int row, int col, Orient direction) {Node* newbody = new Node;newbody->row = row;newbody->col = col;newbody->direction = direction;newbody->next = snakeHead;snakeHead = newbody;}virtual ~Snake() {Node *p = snakeHead, *q=NULL;while (p != NULL) {q = p->next;delete p;p = q;}}
};class Board {
private:Snake* s;int playground[HEIGHT][WIDTH] = {0};Food* food;bool foodIsEaten;bool gameOver;int score;int flushRate;public:Board(int sr=HEIGHT/2, int sc=WIDTH/2, Orient sori=Orient::RIGHT):gameOver(false),foodIsEaten(false),score(INIT_SCORE),flushRate(INIT_FLUSHRATE){s = new Snake(sr, sc, sori);playground[sr][sc] = 1;food = new Food;while ((food->frow = rand() % HEIGHT) == sr);while ((food->fcol = rand() % WIDTH) == sc);playground[food->frow][food->fcol] = 2;}void refresh() {s->move();Node* shead = s->getHead();if((gameOver = isCollision(shead)))return;if (shead->row == food->frow && shead->col == food->fcol) {foodIsEaten = true;switch (shead->direction){case Orient::UP: s->longer(shead->row - 1, shead->col, shead->direction); break;case Orient::DOWN: s->longer(shead->row + 1, shead->col, shead->direction); break;case Orient::LEFT: s->longer(shead->row, shead->col - 1, shead->direction); break;case Orient::RIGHT: s->longer(shead->row, shead->col + 1, shead->direction); break;default:break;}}if (foodIsEaten)refreshFood();memset(playground, 0, sizeof(playground));Node* p = s->getHead();while (p != NULL) {playground[p->row][p->col] = 1;p = p->next;}if(!foodIsEaten)playground[food->frow][food->fcol] = 2;}void printBoard() {for (int i = 0; i < HEIGHT; ++i) {for (int j = 0; j < WIDTH; ++j)playground[i][j] == 1 ? cout << BODY : (playground[i][j]==2? cout << FOOD:cout << EMPTY);i==0?cout << EDGE << "  Your score: " << score << '\n':cout << EDGE << '\n';}for (int k = 0; k < WIDTH; ++k)cout << EDGE;}void setSnakeOrient(Orient ori) {s->setOrient(ori);}void refreshFood() {score++;if(flushRate>50)flushRate-=5;Node* p = s->getHead();while (FoodInSnake(food->frow = rand() % HEIGHT, food->fcol = rand() % WIDTH, p));foodIsEaten = false;}void keyCheck() {if (_kbhit()) {keyIsput = true;char key = _getch();switch (key){case 'w':case'W':setSnakeOrient(Orient::UP); break;case 'a':case'A':setSnakeOrient(Orient::LEFT); break;case 's':case'S':setSnakeOrient(Orient::DOWN); break;case 'd':case'D':setSnakeOrient(Orient::RIGHT); break;default:break;}}}bool isCollision(Node*& head){if(head->row<0 || head->row>=HEIGHT)return true;if(head->col<0 || head->col>=WIDTH)return true;Node* p = head;while(p!=NULL){if(p!=head && p->row==head->row && p->col==head->col)return true;p = p->next;}return false;}int getFlushRate() const{return flushRate;}bool isGameOver(){return gameOver;}void printEnd(){ifstream fin(RANKFILE);if(!fin){fin.close();ofstream fout(RANKFILE);fout << score;fout.close();}else{set<int> r;int tmp;r.insert(score);while(!fin.eof()){fin >> tmp;r.insert(tmp);}fin.close();ofstream fout(RANKFILE);for(auto i=r.rbegin();i!=r.rend();++i)++i==r.rend()?fout << *(--i):fout << *(--i) << '\n';fout.close();}cout << "Game Over!!\n";cout << "Your score is " << score << ".\n";}~Board() {delete s;delete food;}
};Orient Snake::tmp_1 = Orient::RIGHT, Snake::tmp_2 = Orient::RIGHT;int main(int argc, char* argv[]) {if(argc!=2 || (strcmp(argv[1], "start")!=0 && strcmp(argv[1], "rank")!=0)){cerr << "Usage: \"snake start\" to begin game.\n";cerr << "       \"snake rank\" to look rank(1-5).";return 1;}if(strcmp(argv[1], "rank")==0){printRank();return 0;}srand((unsigned)time(NULL));Board* gameboard = new Board();while (!gameboard->isGameOver()) {gameboard->printBoard();Sleep(gameboard->getFlushRate());system("cls");gameboard->keyCheck();gameboard->refresh();}gameboard->printEnd();delete gameboard;return 0;
}

5 游戏截图

在这里插入图片描述

在这里插入图片描述

6 小结

程序中使用了windows的库,所以暂时只支持win系统运行,这个游戏可以说是人人皆知,博主小时候特别喜欢这个游戏,现在动手实现了,感觉还是很不错的。再次感谢各位的阅读,希望可以帮到各位,喜欢的可以点赞支持一波,Thank you very much!!

后话:想学习C语言的,可以看看博主的C现代方法笔记的文章哦!

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

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

相关文章

【小白专用】(C#)用户、角色、权限控制体系

我们在开发很多项目的时候,都会用到用户权限管理,我也在很多项目里做过权限控制,所以,我也总结出一套条理清晰的角色权限控制体系。本文采用RBAC&#xff08;Role Based Access Control&#xff09;的基本思想&#xff0c;RBAC&#xff08;角色访问控制&#xff09;的基本思想可…

Asp .Net Web应用程序(.Net Framework4.8)网站发布到IIS

开启IIS 如果已开启跳过这步 打开控制面板-程序 打开IIS 发布Web程序&#xff08;.Net Framework 4.8 web网页&#xff09; 进入IIS管理器新建一个应用池 新建一个网站 网站创建完毕 为文件夹添加访问权限 如果不添加访问权限&#xff0c;运行时将会得到如下错误 设置权限 勾…

MongoDB高级集群架构设计

两地三中心集群架构设计 容灾级别 RPO & RTO RPO&#xff08;Recovery Point Objective&#xff09;&#xff1a;即数据恢复点目标&#xff0c;主要指的是业务系统所能容忍的数据丢失量。RTO&#xff08;Recovery Time Objective&#xff09;&#xff1a;即恢复时间目标&…

积萨伯爵不懈追求恒久卓越,花为缘集团不断探索时尚的型格魅力

近年来&#xff0c;高端腕表凭借着卓越的制表技艺、悠久的制表历史以及不拘一格的美学特色&#xff0c;逐渐受到各大明星演员&#xff0c;时尚博主的青睐&#xff0c;成为他们出席各大重要场合&#xff0c;彰显个人品位和地位的时尚百搭单品。 积萨伯爵作为专业做培育珠宝和高…

运用tomcat在浏览器中对数据库信息进行查询

在idea中创建好项目后&#xff0c;添加web项目 然后打开idea的setting&#xff0c;跳转到下面的页面&#xff0c;下载maven插件。 出现下面的选项&#xff0c;才正确。 添加好web项目后&#xff0c;打开pom文件&#xff0c;添加相应的依赖&#xff1a; <?xml version"…

“单项突出”的赢双科技IPO加速,比亚迪是最强助力?

近日&#xff0c;新能源汽车核心部件供应商赢双科技首次递表科创板&#xff0c;其凭借旋转变压器产品就坐稳了新能源车企主要供应商的地位&#xff0c;从核心业务及业绩情况来看&#xff0c;赢双科技不愧为“单项冠军”。 据悉&#xff0c;赢双科技本次IPO拟募资8.47亿元&…

Windows内存管理(一):Windows性能监视器(PerfMon)

一、什么是性能监视器 什么是性能监视器&#xff1f; (What is Performance Monitor? )很多时候&#xff0c;我们的计算机只是停止响应、意外关闭或行为异常。这种行为可能有多种原因&#xff0c;指出确切原因可能会有很大帮助。Windows有一个名为Performance Monitor的工具&…

自动驾驶HWP的功能定义

一、功能定义 高速路自动驾驶功能HWP是指在一般畅通高速公路或城市快速路上驾驶员可以放开双手双脚&#xff0c;同时注意力可在较长时间内从驾驶环境中转移&#xff0c;做一些诸如看手机、接电话、看风景等活动&#xff0c;该系统最低工作速度为60kph。 如上两种不同环境和速度…

CSAPP cache lab - Optimizing Matrix Transpose

CSAPP cache lab part B 矩阵转置 矩阵转置是一种操作&#xff0c;它将矩阵的行和列互换位置&#xff0c;即将原始矩阵的行变为转置矩阵的列&#xff0c;将原始矩阵的列变为转置矩阵的行。转置操作可以通过改变矩阵的布局来方便地进行某些计算和分析。 假设有一个mn的矩阵A&…

基于卷积神经的车牌识别系统

项目介绍 本项目是一个基于卷积神经网络的车牌识别系统&#xff0c;旨在通过图像识别技术自动检测和识别车牌&#xff0c;并判断车牌类型。系统可以识别蓝牌、黄牌&#xff08;单双行&#xff09;、绿牌、大型新能源&#xff08;黄绿&#xff09;、领使馆车牌、警牌、武警牌&a…

对接讯飞聊天机器人接口--复盘

1、准备工作 1&#xff09;、进入以下平台进行注册&#xff0c;登录后&#xff0c;点击红框处 2&#xff09;、点击个人免费包&#xff08;会弹出实名认证&#xff0c;先进行实名认证&#xff09; 3&#xff09;、认证后&#xff0c;会进入以下界面&#xff0c;先添加应用 4&am…

Bito智能辅助编程体验报告

Bito智能辅助编程体验报告 1 Bito 能够为我们做些什么事&#xff1f; 号称 IDE 的“瑞士军刀”&#xff0c;可以提升开发 10 倍的效率; 生成代码&#xff1a;要求 Bito 使用自然语言提示生成任何语言的代码。&#xff08;例如&#xff0c;编写一个 Java 函数将数字从一种基数转…