我大概在一个多月前把自己上学期写的c代码的贪吃蛇游戏push到csdn上,并且说c风格的贪吃蛇写起来有些麻烦(贪吃蛇游戏的c语言实现),准备用面向对象的c++再写一遍。现在我们专业恰好刚教完了c++,学校也布置了一道简单的贪吃蛇的编程题目,实现下来,的确觉得c++的思路清晰很多,所以再次把c++的代码push上来,供大家对比参考:)
直接上代码,c++把整个游戏拆分成几个文件,分开上,有一定的c++基础的同学应该可以很容易看懂。
1、全局头文件(global.hpp)
#ifndef _GLOBAL_H_ #define _GLOBAL_H_ #ifndef SYMBOLS #define HEAD '@' #define BODY 'X' #define EMPTY '+' #define FOOD '$' #endif // !SYMBOLS enum direction { up = 0, down = 1, left = 2, right = 4, freeze = 5 }; struct point { int x; int y; point(int x = 0, int y = 0) : x(x), y(y) {} point(const point& another) : x(another.x), y(another.y) {} point& operator=(const point& other) { x = other.x; y = other.y; return *this; } friend bool operator==(const point& point1, const point& point2) { return point1.x == point2.x && point1.y == point2.y; } point& move(direction d) { switch (d) { case up: x--; break; case down: x++; break; case left: y--; break; case right: y++; break; case freeze: default: break; } return *this; } }; #endif // !_GLOBAL_H_
2、snake类的声明和实现(snake.hpp)
(为了简化结构,把声明和实现共同放在了hpp文件里,减少了一点封装性,实际上应该分开头文件和实现文件好一点)
此处使用了容器list作为蛇身(body)的表达形式,这样可以非常方便地进行表达,读者有兴趣可以用数组实现一下,一不小心就会出现有趣的内存错误。。。
#ifndef _SNAKE_H_ #define _SNAKE_H_ #include <iostream> #include <list> #include "global.hpp" class snake { point head; std::list<point> body; public: snake(point initial_head); snake(); ~snake() {} point& getHead(); std::list<point>& getbody(); void grow(point); void setHead(point); }; snake::snake() { head.x = 0; head.y = 0; } snake::snake(point initial_head) { setHead(initial_head); } void snake::setHead(point _head) { head = _head; } void snake::grow(point second_node) { this -> body.push_front(second_node); } point& snake::getHead() { return head; } std::list<point>& snake::getbody() { return body; } #endif
3、map类的声明和实现(map.hpp)
在这里,map中应该包含一个snake类作为组合关系。
在组合关系里面,想要直接修改snake的各种参数是不可行的,所以在前面snake类的声明里加上了诸如setHead(), getHead(), getbody() 这一类的函数。
#ifndef _MAP_H_ #define _MAP_H_ #include <iostream> #include "global.hpp" #include "snake.hpp" class map { private: char** _map; snake _snake; int height, width; std::list<point> foods; public: map(); map(point initial_size, point initial_head, std::list<point> initial_foods); ~map(); void move(direction d); void print(); bool isGameOver(); bool isEat();; void makemap(void); }; map::map() { _map = NULL; height = width = 0; } void map::makemap() { // 这个是用来更新地图的 for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) _map[i][j] = 0; } for (std::list<point>::iterator i = foods.begin(); i != foods.end(); ++i) { _map[i->x][i->y] = FOOD; } _map[_snake.getHead().x][_snake.getHead().y] = HEAD; for (std::list<point>::iterator i = _snake.getbody().begin(); i != _snake.getbody().end(); ++i) { _map[i->x][i->y] = BODY; } for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { if (_map[i][j] == 0) _map[i][j] = EMPTY; } } } map::map(point initial_size, point initial_head, std::list<point> initial_foods) { height = initial_size.x; width = initial_size.y; _map = new char*[height]; for (int i = 0; i < height; i++) _map[i] = new char[width](); _snake.setHead(initial_head); foods = initial_foods; makemap(); } map::~map() { for (int i = 0; i < height; i++) { delete []_map[i]; } delete []_map; } void map::print() { for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { std::cout << _map[i][j]; } std::cout << std::endl; } std::cout << std::endl; } bool map::isGameOver() { point temp = _snake.getHead(); if (temp.x == height || temp.y == width || temp.x < 0 || temp.y < 0) return true; if (_map[temp.x][temp.y] == BODY) return true; return false; } bool map::isEat() { point temp = _snake.getHead(); if (temp.x == height || temp.y == width || temp.x < 0 || temp.y < 0) return false; if (_map[temp.x][temp.y] == FOOD) return true; else return false; } void map::move(direction d) { point temp_f = _snake.getHead(); if (!(_snake.getbody().empty())) { // 为了避免追尾问题 _map[_snake.getbody().back().x][_snake.getbody().back().y] = EMPTY; } _snake.getHead().move(d); if (_snake.getHead() == _snake.getbody().front()) { // 判断蛇是否往回走 _snake.setHead(temp_f); _map[_snake.getbody().back().x][_snake.getbody().back().y] = BODY; return; } if (!isGameOver()) { if (isEat()) { point eaten = _snake.getHead(); foods.remove(eaten); _snake.grow(temp_f); } else { _snake.getbody().push_front(temp_f); _snake.getbody().pop_back(); } makemap(); } else { if (!(_snake.getbody().empty())) { _map[_snake.getbody().back().x][_snake.getbody().back().y] = BODY; } } } #endif
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/482307.html