1 #include <windows.h> 2 #include <stdlib.h> 3 #include <conio.h> 4 #include <time.h> 5 #include <cstring> 6 #include <cstdio> 7 #include <iostream> 8 #define N 22 9 using namespace std; 10 11 int gameover; 12 13 int x1, y1; // 随机出米 14 15 int x,y; 16 17 long start; 18 19 //======================================= 20 //类的实现与应用initialize 21 //======================================= 22 23 //下面定义贪吃蛇的坐标类 24 class snake_position 25 { 26 public: 27 28 int x,y; //x表示行,y表示列 29 30 snake_position(){}; 31 32 void initialize(int &);//坐标初始化 33 34 35 }; 36 37 snake_position position[(N-2)*(N-2)+1]; //定义贪吃蛇坐标类数组,有(N-2)*(N-2)个坐标 38 39 void snake_position::initialize(int &j) 40 { 41 x = 1; 42 43 y = j; 44 } 45 46 47 //下面定义贪吃蛇的棋盘图 48 49 class snake_map 50 { 51 52 private: 53 54 char s[N][N];//定义贪吃蛇棋盘,包括墙壁。 55 56 int grade, length; 57 58 int gamespeed; //前进时间间隔 59 60 char direction; // 初始情况下,向右运动 61 62 int head,tail; 63 64 int score; 65 66 bool gameauto; 67 68 public: 69 70 snake_map(int h=4,int t=1,int l=4,char d=77,int s=0):length(l),direction(d),head(h),tail(t),score(s){} 71 72 void initialize(); //初始化函数 73 74 void show_game(); 75 76 int updata_game(); 77 78 void setpoint(); 79 80 void getgrade(); 81 82 void display(); 83 84 85 }; 86 87 //定义初始化函数,将贪吃蛇的棋盘图进行初始化 88 89 void snake_map::initialize() 90 { 91 int i,j; 92 93 for(i=1;i<=3;i++) 94 95 s[1][i] = ‘*‘; 96 97 s[1][4] = ‘#‘; 98 99 for(i=1;i<=N-2;i++) 100 101 for(j=1;j<=N-2;j++) 102 103 s[i][j]=‘ ‘; // 初始化贪吃蛇棋盘中间空白部分 104 105 for(i=0;i<=N-1;i++) 106 107 s[0][i] = s[N-1][i] = ‘-‘; //初始化贪吃蛇棋盘上下墙壁 108 109 for(i=1;i<=N-2;i++) 110 111 s[i][0] = s[i][N-1] = ‘|‘; //初始化贪吃蛇棋盘左右墙壁 112 } 113 114 115 //============================================ 116 //输出贪吃蛇棋盘信息 117 118 void snake_map::show_game() 119 120 { 121 122 system("cls"); // 清屏 123 124 int i,j; 125 126 cout << endl; 127 128 for(i=0;i<N;i++) 129 { 130 131 cout << ‘\t‘; 132 133 for(j=0;j<N;j++) 134 135 cout<<s[i][j]<<‘ ‘; // 输出贪吃蛇棋盘 136 137 if(i==2) cout << "\t等级:" << grade; 138 139 if(i==6) cout << "\t速度:" << gamespeed; 140 141 if(i==10) cout << "\t得分:" << score << "分" ; 142 143 if(i==14) cout << "\t暂停:按一下空格键" ; 144 145 if(i==18) cout << "\t继续:按两下空格键" ; 146 147 cout<<endl; 148 } 149 } 150 151 //输入选择等级 152 void snake_map::getgrade() 153 { 154 cin>>grade; 155 156 while( grade>7 || grade<1 ) 157 { 158 cout << "请输入数字1-7选择等级,输入其他数字无效" << endl; 159 160 cin >> grade; 161 } 162 switch(grade) 163 { 164 case 1: gamespeed = 1000;gameauto = 0;break; 165 166 case 2: gamespeed = 800;gameauto = 0;break; 167 168 case 3: gamespeed = 600;gameauto = 0;break; 169 170 case 4: gamespeed = 400;gameauto = 0;break; 171 172 case 5: gamespeed = 200;gameauto = 0;break; 173 174 case 6: gamespeed = 100;gameauto = 0;break; 175 176 case 7: grade = 1;gamespeed = 1000;gameauto = 1;break; 177 178 } 179 180 } 181 182 //输出等级,得分情况以及称号 183 184 void snake_map::display() 185 { 186 187 cout << "\n\t\t\t\t等级:" << grade; 188 189 cout << "\n\n\n\t\t\t\t速度:" << gamespeed; 190 191 cout << "\n\n\n\t\t\t\t得分:" << score << "分" ; 192 193 } 194 195 //随机产生米 196 void snake_map::setpoint() 197 { 198 srand(time(0)); 199 200 do 201 { 202 203 x1 = rand() % (N-2) + 1; 204 205 y1 = rand() % (N-2) + 1; 206 207 }while(s[x1][y1]!=‘ ‘); 208 209 s[x1][y1]=‘*‘; 210 } 211 212 char key; 213 214 int snake_map::updata_game() 215 { 216 gameover = 1; 217 218 key = direction; 219 220 start = clock(); 221 222 while((gameover=(clock()-start<=gamespeed))&&!kbhit()); 223 224 //如果有键按下或时间超过自动前进时间间隔则终止循环 225 226 227 228 if(gameover) 229 { 230 231 getch(); 232 233 key = getch(); 234 } 235 236 if(key == ‘ ‘) 237 238 { 239 while(getch()!=‘ ‘){};//这里实现的是按空格键暂停,按空格键继续的功能,但不知为何原因,需要按两下空格才能继续。这是个bug。 240 } 241 242 else 243 244 direction = key; 245 246 switch(direction) 247 { 248 case 72: x= position[head].x-1; y= position[head].y;break; // 向上 249 250 case 80: x= position[head].x+1; y= position[head].y;break; // 向下 251 252 case 75: x= position[head].x; y= position[head].y-1;break; // 向左 253 254 case 77: x= position[head].x; y= position[head].y+1; // 向右 255 256 } 257 258 if(!(direction==72||direction==80||direction==75 ||direction==77)) // 按键非方向键 259 260 gameover = 0; 261 262 else if(x==0 || x==N-1 ||y==0 || y==N-1) // 碰到墙壁 263 264 gameover = 0; 265 266 else if(s[x][y]!=‘ ‘&&!(x==x1&&y==y1)) // 蛇头碰到蛇身 267 268 gameover = 0; 269 270 else if(x==x1 && y==y1) 271 272 { // 吃米,长度加1 273 274 length ++; 275 276 if(length>=8 && gameauto) 277 278 { 279 280 length -= 8; 281 282 grade ++; 283 284 if(gamespeed>=200) 285 286 gamespeed -= 200; // 改变贪吃蛇前进速度 287 288 else 289 290 gamespeed = 100; 291 292 } 293 294 s[x][y]= ‘#‘; //更新蛇头 295 296 s[position[head].x][position[head].y] = ‘*‘; //吃米后将原先蛇头变为蛇身 297 298 head = (head+1) % ( (N-2)*(N-2) ); //取蛇头坐标 299 300 position[head].x = x; 301 302 position[head].y = y; 303 304 show_game(); 305 306 gameover = 1; 307 308 score += grade*20; //加分 309 310 setpoint(); //产生米 311 312 } 313 314 else 315 { // 不吃米 316 317 s[position[tail].x][position[tail].y]=‘ ‘;//将蛇尾置空 318 319 tail= (tail+1) % ( (N-2) * (N-2) );//更新蛇尾坐标 320 321 s[position[head].x][position[head].y]=‘*‘; //将蛇头更为蛇身 322 323 head= (head+1) % ( (N-2) * (N-2) ); 324 325 position[head].x = x; 326 327 position[head].y = y; 328 329 s[position[head].x][position[head].y]=‘#‘; //更新蛇头 330 331 gameover = 1; 332 333 } 334 return gameover; 335 336 } 337 //==================================== 338 //主函数部分 339 //==================================== 340 int main() 341 { 342 char ctn = ‘y‘; 343 344 int nodead; 345 346 cout<<"\n\n\n\n\n\t\t\t 欢迎进入贪吃蛇游戏!"<<endl;//欢迎界面; 347 348 cout<<"\n\n\n\t\t\t 按任意键马上开始。。。"<<endl;//准备开始;; 349 350 getch(); 351 352 while( ctn==‘y‘ ) 353 { 354 system("cls"); // 清屏 355 356 snake_map snake; 357 358 snake.initialize(); 359 360 cout << "\n\n请输入数字选择游戏等级:" << endl; 361 362 cout << "\n\n\n\t\t\t1.等级一:速度 1000 \n\n\t\t\t2.等级二:速度 800 \n\n\t\t\t3.等级三:速度 600 "; 363 364 cout << "\n\n\t\t\t4.等级四:速度 400 \n\n\t\t\t5.等级五:速度 200 \n\n\t\t\t6.等级六:速度 100 \n\n\t\t\t7.自动升级模式" << endl; 365 366 snake.getgrade();//获取等级 367 368 for(int i=1;i<=4;i++) 369 { 370 position[i].initialize(i);//初始化坐标 371 } 372 373 snake.setpoint(); // 产生第一个米 374 375 do 376 { 377 snake.show_game(); 378 379 nodead = snake.updata_game(); 380 381 }while(nodead); 382 383 system("cls"); //清屏 384 385 386 387 cout << "\n\n\n\t\t\t\tGameover!\n\n"<<endl; 388 389 snake.display();//输出等级/得分情况 390 391 cout << "\n\n\n\t\t 是否选择继续游戏?输入 y 继续,n 退出" << endl; 392 393 cin >> ctn; 394 395 } 396 397 return 0; 398 }
时间: 2024-10-17 03:35:00