贪吃蛇
转自http://blog.csdn.net/angle555945/article/details/7649288
神一般的牛~~~~
1 //***************************// 2 // SNAKE C++ // 3 // Written by zhsl // 4 // 2012.6.10 // 5 //***************************// 6 #include<iostream.h> 7 #include<stdio.h> 8 #include<string.h> 9 #include<windows.h> 10 #include<time.h> 11 #include<stdlib.h> 12 #include<conio.h> 13 const int WIDTH=18,LENGTH=58,MID=41; //定义地图长和宽,MID为中间分界线 14 const int INIT_SNAKE_W=4,INIT_SNAKE_L=5; //蛇初始坐标 15 const int INIT_SCORES_W=3,INIT_SCORES_L=43; //scores显示初始位置 16 const int INIT_SPEED_W=8,INIT_SPEED_L=43; //speed显示初始位置 17 const int SPEED_CYCLE=8,SPEED_LOWER=30; //设置加速周期和最大速度 18 const int TIME_DWELL=1000; 19 20 /**********自定义数据**********/ 21 struct NODE_COMMON{int x,y;}; //点集 22 struct NODE_SNAKE{ //蛇点集 23 int x,y; 24 NODE_SNAKE *next; 25 }; 26 int Speed_Boost[6]={0,-50,-35,-35,-25,-16},K=0; //设置加速周期和加速周期点 27 int Dir_x[4]={0,2,0,-2},Dir_y[4]={-1,0,1,0}; 28 int Snake_Map[WIDTH+1][LENGTH+1]; 29 int Has_Bean; 30 int Speed=200,Num_Speed=1; 31 int Scores; 32 int Is_Gameover=0; 33 int Is_Press; 34 NODE_COMMON BEAN; 35 36 /**********获取句柄**********/ 37 HANDLE Output=GetStdHandle(STD_OUTPUT_HANDLE); 38 HANDLE Input=GetStdHandle(STD_INPUT_HANDLE); 39 40 /**********设置光标位置**********/ 41 void SetCursor(int x,int y){ 42 COORD cd={x,y}; 43 SetConsoleCursorPosition(Output,cd); 44 } 45 46 /**********FLASH类**********/ 47 class FLASH 48 { 49 public: 50 FLASH(){ 51 picture_width=18;picture_length=80; 52 strcpy(character,"The direction key control movement"); 53 character_len=strlen(character); 54 }; 55 void Init_Picture(); //初始化picture 56 void Flash_Snake(); //Display picture 57 private: 58 char character[60],character_len; 59 char picture[20][160],picture_dis[20][160]; 60 int picture_width,picture_length; 61 }; 62 void FLASH::Init_Picture(){ //初始化Flash 63 memset(picture,32,sizeof(picture)); 64 memset(picture,32,sizeof(picture_dis)); 65 strcpy(picture[0]+80, " "); 66 strcpy(picture[1]+80, " "); 67 strcpy(picture[2]+80, " /^\\/^\\ "); 68 strcpy(picture[3]+80, " _|__| O| "); 69 strcpy(picture[4]+80, " \\/ /~ \\_/ \\ "); 70 strcpy(picture[5]+80, " \\____|__________/ \\ "); 71 strcpy(picture[6]+80, " \\_______ \\ "); 72 strcpy(picture[7]+80, " `\\ \\ "); 73 strcpy(picture[8]+80, " | | "); 74 strcpy(picture[9]+80, " / / \\ "); 75 strcpy(picture[10]+80," / / \\\\ "); 76 strcpy(picture[11]+80," / / \\ \\ "); 77 strcpy(picture[12]+80," / / \\ \\ "); 78 strcpy(picture[13]+80," / / _----_ \\ \\ "); 79 strcpy(picture[14]+80," / / _-~ ~-_ | | "); 80 strcpy(picture[15]+80," ( ( _-~ _--_ ~-_ _/ | "); 81 strcpy(picture[16]+80," \\ ~-____-~ _-~ ~-_ ~-_-~ / "); 82 strcpy(picture[17]+80," ~-_ _-~ ~-_ _-~ "); 83 strcpy(picture[18]+80, " ~--______-~ ~-___-~ "); 84 for(int i=0;i<=picture_width;i++) 85 strcpy(picture_dis[i],picture[i]); 86 } 87 void FLASH::Flash_Snake() 88 { 89 int i,j,speed; 90 speed=80; 91 for(i=0;i<picture_length-3;i++){ 92 SetCursor(0,0); 93 for(j=0;j<=picture_width;j++){ 94 picture_dis[j][79+i]='\0'; 95 printf("%s\n",picture_dis[j]+i); 96 picture_dis[j][79+i]=picture[j][79+i]; 97 } 98 Sleep(speed); 99 speed-=1; 100 } 101 SetCursor(33,6); 102 speed=66; 103 for(i=0;i<character_len;i++){ 104 printf("%c",character[i]); 105 Sleep(speed); 106 speed-=2; 107 } 108 } 109 110 /**********MAP类**********/ 111 class MAP 112 { 113 public: 114 MAP(int w,int l,int m){ 115 width=w; 116 length=l; 117 mid=m; 118 memset(map,32,sizeof(map)); 119 } 120 void Init_Map(){ //初始化地图 121 int i; 122 for(i=0;i<width;i++)map[i][length]='\0'; 123 for(i=1;i<width-1;i++) 124 map[i][0]=map[i][mid]=map[i][mid+1]=map[i][length-1]='|'; 125 for(i=1;i<mid;i++)map[0][i]=map[width-1][i]='-'; 126 for(i+=2;i<length-1;i++)map[0][i]=map[width-1][i]='-'; 127 } 128 void Display_Map(){ //输出地图到屏幕 129 for(int i=0;i<width;i++) 130 printf("%s\n",map[i]); 131 } 132 private: 133 int width,length,mid; //整个地图的宽和长,mid为中间分界线 134 char map[WIDTH+1][LENGTH+1]; 135 }; 136 137 /**********MESSAGE类**********/ 138 class MESSAGE 139 { 140 public: 141 MESSAGE(){ 142 num_speed=0;w=2; 143 SetCursor(46,14); 144 printf("Written"); 145 SetCursor(46,15); 146 printf("by zhsl"); 147 } 148 void Init_Message(); //初始化消息 149 void Put_Message(); //Display message 150 private: 151 int w; 152 int num_speed; 153 }; 154 void MESSAGE::Init_Message(){ 155 SetCursor(INIT_SCORES_L,INIT_SCORES_W); 156 printf("====Scores===="); 157 SetCursor(INIT_SPEED_L,INIT_SPEED_W); 158 printf("====Speed====="); 159 } 160 void MESSAGE::Put_Message(){ 161 SetCursor(INIT_SCORES_L,INIT_SCORES_W+2); 162 printf(" %3d",Scores); 163 if(Num_Speed>num_speed && K<6){ 164 SetCursor(INIT_SPEED_L+w,INIT_SPEED_W+2); 165 w+=2; 166 num_speed++; 167 Speed+=Speed_Boost[K++]; 168 printf(">"); 169 } 170 } 171 172 /**********SNAKE类**********/ 173 class SNAKE{ 174 public: 175 SNAKE(){ 176 head=rear=NULL; 177 dir=1; 178 } 179 static int Is_Lived(int x,int y,NODE_SNAKE *rear); //SNAKE是否能gameover 180 void Init_Snake(); //初始化SNAKE 181 void Move_Snake(); //SNAKE移动并display 182 void Change_Direct(int d){dir=d;} //改变蛇的移动方向 183 int Get_Dir(){return dir;} 184 NODE_SNAKE Get_Head(){return *head;} 185 NODE_SNAKE Get_Rear(){return *rear;} 186 private: 187 friend void Put_Snake(); 188 NODE_SNAKE *head,*rear; 189 int dir; 190 }; 191 int SNAKE::Is_Lived(int x,int y,NODE_SNAKE *rear){ 192 if(x>0&&x<MID && y>0&&y<WIDTH-1 && (Snake_Map[y][x]==0 || (x==rear->x && y==rear->y) )) return 1; 193 else return 0; 194 } 195 void SNAKE::Init_Snake(){ 196 int i; 197 NODE_SNAKE *q; 198 rear=new NODE_SNAKE; 199 rear->x=INIT_SNAKE_L,rear->y=INIT_SNAKE_W; 200 Snake_Map[INIT_SNAKE_W][INIT_SNAKE_L]=1; 201 rear->next=NULL; 202 head=rear; 203 for(i=2;i<6;i+=2){ 204 q=new NODE_SNAKE; 205 q->x=INIT_SNAKE_L+i; 206 q->y=INIT_SNAKE_W; 207 Snake_Map[INIT_SNAKE_W][INIT_SNAKE_L+i]=1; 208 q->next=NULL; 209 head->next=q; 210 head=q; 211 } 212 for(q=rear;q;q=q->next){ 213 SetCursor(q->x,q->y); 214 printf("■"); 215 } 216 } 217 void SNAKE::Move_Snake(){ 218 NODE_SNAKE *q=new NODE_SNAKE; 219 q->x=head->x+Dir_x[dir]; 220 q->y=head->y+Dir_y[dir]; 221 q->next=NULL; 222 head->next=q; 223 head=q;q=rear; 224 if(!SNAKE::Is_Lived(head->x,head->y,rear)){ //判断是否游戏结束 225 SetCursor(5,8); 226 printf(" Game Over! \n"); 227 SetCursor(5,9); 228 printf(" \n"); 229 SetCursor(5,10); 230 printf(" Press the Enter to continue \n"); 231 SetCursor(5,11); 232 printf(" Press the Esc to exit \n"); 233 SetCursor(LENGTH-1,WIDTH-1); 234 Is_Gameover=1; 235 return; 236 } 237 if(head->x!=BEAN.x || head->y!=BEAN.y){ //判断是否吃到BEAN 238 SetCursor(rear->x,rear->y); 239 printf(" "); 240 Snake_Map[rear->y][rear->x]=0; 241 rear=rear->next; 242 delete q; 243 } 244 else {Has_Bean=0;Scores++;Num_Speed=Scores/SPEED_CYCLE+1;} //吃到BEAN 245 SetCursor(head->x,head->y); 246 printf("■"); 247 Snake_Map[head->y][head->x]=1; 248 } 249 250 /**********BEAN函数**********/ 251 void Put_Bean() 252 { 253 int x,y; 254 while(!Has_Bean){ 255 srand((unsigned)time(NULL)); 256 x=rand()%(MID-2)+1; 257 if(!(x&1))x++; 258 y=rand()%(WIDTH-2)+1; 259 if(!Snake_Map[y][x]){ 260 SetCursor(x,y); 261 printf("●"); 262 Has_Bean=1; 263 BEAN.x=x,BEAN.y=y; 264 } 265 } 266 } 267 268 /**********MAIN**********/ 269 int main() 270 { 271 /**********FLASH**********/ 272 FLASH flash; 273 flash.Init_Picture(); 274 flash.Flash_Snake(); 275 Sleep(TIME_DWELL*3); //停顿 276 /**********INI MAP**********/ 277 while(true) 278 { 279 system("cls"); 280 MAP map(WIDTH,LENGTH,MID); 281 map.Init_Map(); 282 map.Display_Map(); 283 /**********INI MESSAGE**********/ 284 MESSAGE message; 285 message.Init_Message(); 286 message.Put_Message(); 287 /**********INI SNAKE**********/ 288 SNAKE snake; 289 snake.Init_Snake(); 290 /**********INI BEAN**********/ 291 Put_Bean(); 292 SetCursor(LENGTH-1,WIDTH-1); 293 Sleep(TIME_DWELL*2); //停顿 294 while(true) 295 { 296 snake.Move_Snake(); 297 if(Is_Gameover){ //游戏是否继续 298 Sleep(800); 299 while(true){ 300 if(GetAsyncKeyState(VK_ESCAPE))exit(0); 301 if(GetAsyncKeyState(13)){ 302 Is_Gameover=0; 303 Has_Bean=0; 304 Speed=200,Num_Speed=1,K=0; 305 Scores=0; 306 memset(Snake_Map,0,sizeof(Snake_Map)); 307 break; 308 } 309 } 310 break; 311 } 312 if(!Has_Bean){Put_Bean();message.Put_Message();} 313 Sleep(Speed); 314 /**********键位响应**********/ 315 if(GetAsyncKeyState(VK_UP) && snake.Get_Dir()!=2 && !Is_Press)snake.Change_Direct(0),Is_Press=1; 316 if(GetAsyncKeyState(VK_DOWN) && snake.Get_Dir()!=0 && !Is_Press)snake.Change_Direct(2),Is_Press=1; 317 if(GetAsyncKeyState(VK_LEFT) && snake.Get_Dir()!=1 && !Is_Press)snake.Change_Direct(3),Is_Press=1; 318 if(GetAsyncKeyState(VK_RIGHT) && snake.Get_Dir()!=3 && !Is_Press)snake.Change_Direct(1),Is_Press=1; 319 Is_Press=0; 320 } 321 } 322 return 0; 323 }