命令行之贪吃蛇
(可能有BUG,时间有限,只能写成这样了)
游戏截图 :
#include <iostream> #include <windows.h> #include <conio.h> #include <time.h> #include <cstdlib> #define Coord_x 15 #define Coord_y 15 #define Height 20 #define Width 18 using namespace std; enum dir{u,d,l,r}; class Snake{ public: int x; int y; int score; int level; int snake_speed; Snake *prior, *next; int vis[100][100]; char map[100][100]; int food_x; int food_y; int init_x; int init_y; dir point; public: Snake(int s = 0, int l = 1, int ss = 200); void init_snake(); void add_head(int x, int y); void delete_tail(); bool make_food(); void change_point(char); void move(); void Display(); }S, *head = NULL, *tail = NULL; class Console{ public: void gotoxy(HANDLE hOut, int x, int y); void enter_game(); void initialize_window(); void start_game(); void end_game(); friend class Snake; }C; void Console::gotoxy(HANDLE hOut, int x, int y) { COORD pos; pos.X = x; pos.Y = y; SetConsoleCursorPosition(hOut, pos); } void Console::enter_game() { HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); system("title 贪吃蛇 by Tc"); gotoxy(hOut,Coord_x+Width+1,Coord_y-11); SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN); cout << "欢迎进入贪吃蛇"; SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_GREEN); gotoxy(hOut,Coord_x+Width-25,Coord_y-8); cout << " * * * * * * * * * * * * " << endl; gotoxy(hOut,Coord_x+Width-25,Coord_y-7); cout << " * * ** * * * * * * " << endl; gotoxy(hOut,Coord_x+Width-25,Coord_y-6); cout << " * * * * * * * * * " << endl; gotoxy(hOut,Coord_x+Width-25,Coord_y-5); cout << " * * * * * * * * * * * * * " << endl; gotoxy(hOut,Coord_x+Width-25,Coord_y-4); cout << " * * * * * * * * * * * * " << endl; gotoxy(hOut,Coord_x+Width-25,Coord_y-3); cout << " * * * * * * * * * " << endl; gotoxy(hOut,Coord_x+Width-25,Coord_y-2); cout << " * * * ** * * * * * " << endl; gotoxy(hOut,Coord_x+Width-25,Coord_y-1); cout << " * * * * * * * * * * * * * " << endl; gotoxy(hOut,Coord_x+Width,Coord_y+3); SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_RED); cout << "按回车键进入游戏\n"<< endl;; SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_GREEN); while(1) { char c; if(kbhit()) { c = getch(); if(c == 13) { system("CLS"); C.initialize_window(); C.start_game(); } } cout << "O" ; Sleep(200); } if(getch() == 27) { C.end_game(); } else { C.enter_game(); } } void Console::end_game() { HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); system("CLS"); SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN); gotoxy(hOut,Coord_x+Width+5,Coord_y-10); cout << "游戏结束"; gotoxy(hOut,Coord_x+Width+5,Coord_y-7); cout << "最终得分 : " << S.score << endl; gotoxy(hOut,Coord_x+Width+5,Coord_y-5); exit(0); } void Console::initialize_window() { HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); system("title 贪吃蛇 by Tc"); system("color 0C"); gotoxy(hOut,Coord_x+Width-4,Coord_y-2); cout << "********"; gotoxy(hOut,Coord_x+Width-3,Coord_y-3); cout << "贪吃蛇"; gotoxy(hOut,Coord_x+Width-4,Coord_y-4); cout << "********"; gotoxy(hOut,Coord_x+2*Width+3,Coord_y-2); SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN); gotoxy(hOut,Coord_x+2*Width+3,Coord_y+Height-18); cout << "得分 : " << S.score << " 等级 : " << S.level; gotoxy(hOut,Coord_x+2*Width+3,Coord_y+Height-12); cout << "w键 : 上 " << "s键 : 下"; gotoxy(hOut,Coord_x+2*Width+3,Coord_y+Height-10); cout << "a键 : 左 " << "d键 : 右"; gotoxy(hOut,Coord_x+2*Width+3,Coord_y+Height-8); cout << "空格键 :暂停"; gotoxy(hOut,Coord_x+2*Width+3,Coord_y+Height-6); cout << "Esc :退出"; SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_GREEN); for(int i = 0;i < 2 * Width - 1; i++) { S.vis[Coord_x + i][Coord_y - 1] = 2; } for(int i = 0;i < 2 * Width - 1; i++) { S.vis[Coord_x + i][Coord_y + Height] = 2; } for(int i = 0;i < 2 * Width-1; i += 2) { gotoxy(hOut,Coord_x + i,Coord_y - 1); cout << "*"; } for(int i = 0;i < 2 * Width-1; i += 2) { gotoxy(hOut,Coord_x + i,Coord_y + Height); cout << "*"; } for(int i = 0;i < Height;i++) { gotoxy(hOut,Coord_x,Coord_y+i); cout << "*"; S.vis[Coord_x][Coord_y+i] = 2; } for(int i = 0;i < Height;i++) { gotoxy(hOut,Coord_x+2*Width-2,Coord_y+i); cout << "*"; S.vis[Coord_x+2*Width-2][Coord_y+i] = 2; } } Snake::Snake(int s, int l, int ss) { score = s; level = l; snake_speed = ss; } void Snake::add_head(int x, int y) { Snake *node = new Snake; node -> x = x; node -> y = y; node -> next = head; node -> prior = NULL; if(head) head -> prior = node; head = node; if(!tail) tail = head; S.map[x][y] = 'O'; S.vis[x][y] = 1; } void Snake::delete_tail() { Snake *t = tail; S.map[ tail -> x ][ tail -> y ]= ' '; S.vis[ tail -> x ][ tail -> y ] = 0; if(tail == head) tail = head = NULL; else { tail = tail -> prior; tail -> next = NULL; } delete t; } void Snake:: init_snake() { srand((unsigned) time(NULL)); S.init_x = Coord_x + 2 + rand() % 20; S.init_y = Coord_y + 2 + rand() % 15; } void Snake::move() { int a, b; a = head -> x; b = head -> y; switch(point) { case u: --b; break; case d: ++b; break; case l: --a; break; case r: ++a; break; } if(S.vis[a][b] == 1 || S.vis[a][b] == 2) { C.end_game(); } if(vis[a][b] == 3) { head -> add_head(a,b); S.vis[a][b] = 1; score += 10; if(score % 50 == 0) { level++; snake_speed -= 20; } while(!S.make_food()); } else { head -> add_head(a,b); head -> delete_tail(); } } void Snake::change_point(char keydown) { switch(keydown) { case 'w': point = u; break; case 's': point = d; break; case 'a': point = l; break; case 'd': point = r; break; } } bool Snake::make_food() { srand((unsigned int) time(NULL)); food_x = Coord_x + 1 + rand() % 34; food_y = Coord_y + 1 + rand() % 18; if(S.vis[food_x][food_y] == 0) { S.map[food_x][food_y] = 'O'; S.vis[food_x][food_y] = 3; return true; } return false; } void Snake:: Display() { HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); for(int i = Coord_x + 1; i < Coord_x + 2 * Width - 2; i++) { for(int j = Coord_y; j < Coord_y + Height; j++) { C.gotoxy(hOut,i,j); if(i == head -> x && j == head -> y) { SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_RED); cout << S.map[i][j]; } else { SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED); cout << S.map[i][j]; } } } SetConsoleTextAttribute(handle,FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED); C.gotoxy(hOut,Coord_x+2*Width+3,Coord_y+Height-18); cout << "得分 : " << score << " 等级 : " << level; } void Console::start_game() { S.init_snake(); head -> add_head(S.init_x,S.init_y); head -> add_head(S.init_x+1,S.init_y); head -> add_head(S.init_x+2,S.init_y); while(!S.make_food()); S.Display(); char keydown = '\0'; while(true) { char temp = keydown; keydown = getch(); if(keydown == 27) { C.end_game(); } S.change_point(keydown); if(keydown == ' ') { S.Display(); while(true) { if(kbhit()) { char ch = getch(); if(ch == ' ') { goto Loop; } } } } if(temp == 'w' && keydown == 's') { S.point = u; keydown = 'w'; } else if(temp == 's' && keydown == 'w') { S.point = d; keydown = 's'; } else if(temp == 'a' && keydown == 'd') { S.point = l; keydown = 'a'; } else if(temp == 'd' && keydown == 'a') { S.point = r; keydown = 'd'; } Loop: while(!kbhit()) { S.move(); S.Display(); Sleep(S.snake_speed); } } } int main() { memset(S.vis,0,sizeof(S.vis)); memset(S.map,0,sizeof(S.map)); C.enter_game(); return 0; }