c++实现贪吃蛇
来源:互联网 发布:科比3d模型数据 编辑:程序博客网 时间:2024/06/08 01:09
```#include<iostream>#include<utility>#include<set>#include<deque>#include<Windows.h>#include <ctime>#include <stdexcept>#include<string>#include<conio.h>WORD SQUARE_COLOR[7] = { FOREGROUND_RED | FOREGROUND_INTENSITY,FOREGROUND_GREEN | FOREGROUND_INTENSITY,FOREGROUND_BLUE | FOREGROUND_INTENSITY,FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY,FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY,FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY,FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY};义方向#define KEY_UP 72#define KEY_DOWN 80#define KEY_LEFT 75#define KEY_RIGHT 77#define KEY_ESC 27//边框属性#define MAPW 30#define MAPH 20#define OFFSET_L 2#define OFFSET_U 2using namespace std;class Bitmap;class Feed;class Snake;//获取句柄函数HANDLE initiate() { HANDLE hOutput; hOutput = GetStdHandle(STD_OUTPUT_HANDLE); return hOutput;}//控制台输出函数bool textout(HANDLE hOutput, int x, int y, LPTSTR lpszCtring,WORD wColors[], int nColors) { DWORD cWritten; BOOL fSuccess; COORD coord; coord.X = x; coord.Y = y; fSuccess = WriteConsoleOutputCharacter( hOutput, lpszCtring, lstrlen(lpszCtring), coord, &cWritten ); for (;fSuccess && coord.X < lstrlen(lpszCtring) + x;coord.X += nColors) { fSuccess = WriteConsoleOutputAttribute( hOutput, wColors, nColors, coord, &cWritten ); } if (!fSuccess) cout << "error:WriteConsoleOutputCharacter" << endl; return 0;}//endbool textout1(HANDLE hOutput,int x,int y,LPTSTR lpszCtring) { DWORD cWritten; BOOL fSuccess; COORD coord; coord.X = x; coord.Y = y; fSuccess = WriteConsoleOutputCharacter( hOutput, lpszCtring, lstrlen(lpszCtring), coord, &cWritten ); if (!fSuccess) cout << "error:WriteConsoleOutputCharacter" << endl; return 0;}enum type { bitmap_type, feed_type, snake_type, none_type,};extern HANDLE handle;//打印游戏界面template<typename T> void print(T &t, enum type ty) { LPTSTR lpszText = TEXT("◆") ; switch (ty) { case bitmap_type: lpszText = TEXT("◆"); break; case feed_type: lpszText = TEXT("●"); break; case snake_type: lpszText = TEXT("■"); break; case none_type: lpszText = TEXT(" "); break; default: runtime_error("无效的背景框!"); break; } for (T::iterator it = t.begin();it != t.end();++it) textout(handle, OFFSET_L + 2 * it->coord.first, OFFSET_U + it->coord.second, lpszText, SQUARE_COLOR+it->color,1);}//Nodestruct Node { pair<int, int> coord; int color; Node(int x,int y,int c):coord(x,y),color(c){} friend inline bool operator<(const Node &lhs, const Node &rhs);};//比较两个节点是否相同的函数bool equalNode(Node node1, Node node2) { if (node1.coord.first == node2.coord.first && node1.coord.second == node2.coord.second) return true; else return false;}//运算符重载(因为set需要排序)inline bool operator<(const Node &lhs, const Node &rhs){ if (lhs.coord.second < rhs.coord.second) { return true; } else if (lhs.coord.second == rhs.coord.second) { return lhs.coord.first < rhs.coord.first; } else { return false; }}//Bitmap 类class Bitmap{public: friend class Feed; friend class Snake; Bitmap(int map_x,int map_y,int map_w,int map_h,int map_c):x(map_x),y(map_y),w(map_w),h(map_h),c(map_c){} void printBitmap(); void Insert(pair<int, int> edge);private: int x, y, w, h, c; set<Node> bm;};void Bitmap::Insert(pair<int, int> edge) { if (edge.first >= x && edge.first <= x + w - 1 && edge.second >= y && edge.second <= y + h - 1) bm.insert(Node(edge.first, edge.second,c)); else throw runtime_error("无效的背景框!");}void Bitmap::printBitmap() { print(bm, bitmap_type);}//feed类class Feed {public: friend class Snake; void PrintFeed();private: set<Node> fd;};void Feed::PrintFeed() { print(fd, feed_type);}class Snake {public: friend class Feed; enum direction { up, down, left, right }; Snake(pair<int, int> head, pair<int, int> tail); void PrintSnake(); void EraseSnake(); void MoveFront(pair<int,int> t); bool NextStep(direction d,Bitmap &b,Feed &fd,bool &eat); void Snake::AddNewFeed(Bitmap &b, Feed &f); direction GetDir() { return this->dir; } bool ChangeDirection(direction d, Bitmap &b, Feed &f, bool &eat); //判断方向改变是否合法private: deque<Node> sn; direction dir; void AddFrontNode(Node n, Feed &f);};Snake::Snake(pair<int, int> head, pair<int, int> tail) { srand(static_cast<unsigned int>(time(NULL))); if (head.first == tail.first) { if (head.second < tail.second) { dir = up; for (int i = head.second;i <= tail.second;++i) sn.push_back(Node(head.first, i,rand()%7)); } else if (head.second > tail.second) { dir = down; for (int i = head.second;i >= tail.second;--i) sn.push_back(Node(head.first, i, rand() % 7)); } else throw runtime_error("无法绘蛇"); } else if (head.second == tail.second) { if (head.first > tail.first) { dir = right; for (int i = head.first;i >= tail.first;--i) sn.push_back(Node(head.second, i, rand() % 7)); } else if (head.first < tail.first) { dir = left; for (int i = head.first;i <= tail.first;++i) sn.push_back(Node(head.second, i, rand() % 7)); } } else throw runtime_error("无法绘蛇");}void Snake::PrintSnake() { print(sn, snake_type);}void Snake::EraseSnake() { print(sn, none_type);}void Snake::AddFrontNode(Node n, Feed &f) { sn.push_front(n); f.fd.erase(n);}void Snake::MoveFront(pair<int,int> t) { for (deque<Node>::reverse_iterator it = sn.rbegin();it != sn.rend();it++) { if (it != sn.rend() - 1) { it->coord.first = (it + 1)->coord.first; it->coord.second = (it + 1)->coord.second; } else { it->coord.first = t.first; it->coord.second = t.second; } }}bool Snake::NextStep(direction d, Bitmap &b, Feed &f, bool &eat) { pair<int, int> temp; //存放头节点 switch (d) { case up: temp.first = sn[0].coord.first; temp.second = sn[0].coord.second - 1; break; case down: temp.first = sn[0].coord.first; temp.second = sn[0].coord.second + 1; break; case left: temp.first = sn[0].coord.first - 1; temp.second = sn[0].coord.second; break; case right: temp.first = sn[0].coord.first + 1; temp.second = sn[0].coord.second; break; default: throw runtime_error("反向无效"); break; } dir = d; for (set<Node>::iterator it = b.bm.cbegin();it != b.bm.cend();it++) if (equalNode(*it, Node(temp.first, temp.second,6))) return false; for (deque<Node>::iterator it = sn.begin();it != sn.end() - 1;it++) if (equalNode(*it, Node(temp.first, temp.second,6))) return false; for (set<Node>::iterator it = f.fd.begin();it != f.fd.end();it++) { if (equalNode(*it, Node(temp.first, temp.second,6))) { eat = true; AddFrontNode(*it, f); AddNewFeed(b, f); f.PrintFeed(); EraseSnake(); PrintSnake(); return true; } } EraseSnake(); MoveFront(temp); PrintSnake(); return true;}bool Snake::ChangeDirection(direction d, Bitmap &b, Feed &f, bool &eat) { if (d == dir) return true; //不执行操作,但继续执行下面的代码 if (dir == up && d == down || dir == down && d == up || dir == left && d == right || dir == right && d == left) return true; return NextStep(d, b, f, eat);}void Snake::AddNewFeed(Bitmap &b, Feed &f) { pair<int, int> temp; bool ok = false; set<Node>::iterator it; srand(static_cast<unsigned int>(time(NULL))); while (1) { temp.first = rand() % b.w + b.x; temp.second = rand() % b.h + b.y; Node node(temp.first, temp.second,6); for (it = b.bm.begin();it != b.bm.end(); it++) { if (equalNode(*it, node)) { ok = false; break; } ok = true; } if (!ok) continue; for (it = f.fd.begin();it != f.fd.end(); it++) { if (equalNode(*it, node)) { ok = false; break; } ok = true; } if (!ok) continue; deque<Node>::iterator dit; for (dit = sn.begin();dit != sn.end();dit++) { if (equalNode(*dit, node)) { ok = false; break; } ok = true; } if (!ok) continue; f.fd.insert(Node(temp.first, temp.second,rand()%7)); break; }}HANDLE handle;void init(Bitmap &b,Feed &feed,Snake &s){ handle = initiate(); for (int i = 0; i < MAPW; i++) { b.Insert(make_pair(i, 0)); b.Insert(make_pair(i, MAPH - 1)); } for (int j = 1; j < MAPH - 1; j++) { b.Insert(make_pair(0, j)); b.Insert(make_pair(MAPW - 1, j)); } b.printBitmap(); for (int i = 0;i < 3;++i) s.AddNewFeed(b, feed); feed.PrintFeed(); s.PrintSnake(); LPTSTR Text1 = TEXT("SCORE:"); LPTSTR Text2 = TEXT("LEVEL:"); LPTSTR Text = TEXT("❤按任意键开始!❤"); textout1(handle, 1, 1, Text); textout1(handle, OFFSET_L + 2*MAPW , OFFSET_U, Text1); textout1(handle, OFFSET_L + 2 * MAPW, OFFSET_U + 5, Text2); char c = _getch();}int main() { srand(static_cast<unsigned int>(time(NULL))); Bitmap myBitmap(0, 0, MAPW, MAPH,rand()%7); Snake mySnake(make_pair(10, 10), make_pair(10, 12)); Feed myFeed; init(myBitmap,myFeed,mySnake); int score = 0, level = 0, max_delay = 70 - 10 * level, uplevel = 5, speed = 6, minspeed = 4; bool ret = true, eat = false; while (1) { //textout(handle, OFFSET_L + 2 * MAPW + 2, 4, string); /*_itoa_s(level, string, 10); textout(handle, OFFSET_L + 2 * MAPW + 2, 15, string);*/ int delay = 0; max_delay = 35 - 5 * level; while (delay < max_delay) { if (_kbhit()) { int key = _getch(); switch (key) { case KEY_UP: ret = mySnake.ChangeDirection(Snake::up, myBitmap, myFeed, eat); break; case KEY_DOWN: ret = mySnake.ChangeDirection(Snake::down, myBitmap, myFeed, eat); break; case KEY_LEFT: ret = mySnake.ChangeDirection(Snake::left, myBitmap, myFeed, eat); break; case KEY_RIGHT: ret = mySnake.ChangeDirection(Snake::right, myBitmap, myFeed, eat); break; case KEY_ESC: exit(EXIT_SUCCESS); } if (!ret) { textout1(handle, OFFSET_L + MAPW / 2, OFFSET_U + MAPH / 2, TEXT("游戏结束")); char c = _getch(); exit(EXIT_SUCCESS); } if (eat) { eat = false; score++; if (score%uplevel == 0) { level++; uplevel += 3; --speed; speed = ((speed == minspeed) ? minspeed : speed); } } } Sleep(speed); delay++; } //while (delay < max_delay) ret = mySnake.NextStep(mySnake.GetDir(), myBitmap, myFeed, eat); if (!ret) { textout1(handle, OFFSET_L + MAPW / 2, OFFSET_U + MAPH / 2, TEXT("游戏结束")); char c = _getch(); exit(EXIT_SUCCESS); } if (eat) { eat = false; score++; if (score%uplevel == 0) { level++; uplevel += 3; --speed; speed = ((speed == minspeed) ? minspeed : speed); } } }//while(1) return 0;}
1 0
- 贪吃蛇C实现
- 贪吃蛇----C语言实现
- C语言实现贪吃蛇
- [C++]C++实现贪吃蛇
- 贪吃蛇游戏(c实现)
- C + SDL 贪吃蛇的基础实现
- 【LB】C语言实现贪吃蛇
- 30行C代码实现贪吃蛇
- c语言实现,图形化贪吃蛇
- 贪吃蛇游戏的C语言实现
- c语言实现贪吃蛇小游戏
- C语言之实现贪吃蛇
- 贪吃蛇C语言实现(简易版)
- C语言用数组实现贪吃蛇
- C语言 贪吃蛇实现(不闪屏)
- 用C语言实现贪吃蛇
- 贪吃蛇——C语言实现
- C语言-贪吃蛇具体实现
- oracle数据库中的多表查询
- 九宫重排问题
- 关于配置码云的时候遇到一个小问题
- java版本kafka createStream
- 配置Docker过程记录
- c++实现贪吃蛇
- Redis在线用户设计
- 微信小程序开发常见问题FAQ之八
- 截屏方法
- 自定义倒计时跳过按钮
- Json对象与Json字符串互转(4种转换方式)
- CTPN: Detecting Text in Natural Image with Connectionist Text Proposal Network
- java版本kafka createDirectStream
- 左右箭头轮播图效果