C++实现2048小游戏
程序员文章站
2022-06-22 10:39:41
代码如下: 图形库地址: https://easyx.cn/downloads/ ......
代码如下:
1 #define _crt_secure_no_warnings//去掉编译器内部扩增问题 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<math.h> 5 #include<graphics.h>//需要下载图形库 6 #include<conio.h> 7 #include<time.h> 8 #include<string> 9 #include<fstream> 10 #include<iostream> 11 #include<sstream> 12 using namespace std; 13 14 namespace 15 { 16 image image[12]; 17 int imageindex[12]; 18 int map[4][4] = { 2 }; 19 bool isover = true; 20 bool gameover = false; 21 enum direction 22 { 23 up, down, left, right 24 }; 25 }; 26 27 void setimageindex();//设置图片编号 28 void loadresource(); 29 void drawmap(); 30 void randintnum(); 31 void keydownanddraw(); 32 bool turnleft(int s[4][4]); 33 void changeonkeydown(direction direction); 34 35 36 37 int main() 38 { 39 setimageindex(); 40 loadresource(); 41 initgraph(60*4,60*4+120);//游戏界面大小 42 drawmap(); 43 keydownanddraw(); 44 system("pause");//防止闪屏 45 //closegraph(); 46 //system("pause"); 47 return 0; 48 } 49 void setimageindex() 50 { 51 imageindex[0] = 0; 52 for (int i = 1; i < 12; i++) 53 { 54 imageindex[i] = int(pow(2, i)); 55 } 56 } 57 void loadresource()//加载图片 58 { 59 for (int i = 0; i < 12; i++) 60 { 61 char filename[20] = ""; 62 sprintf(filename, "%d.bmp", imageindex[i]);//拼接 63 loadimage(image + i, filename,60,60); 64 } 65 } 66 67 //画地图 68 void drawmap() 69 { 70 string out; 71 int histryhighlyscore = 0; 72 ifstream iscore("score.txt");//创建文件读取历史最高分 73 if (!iscore) 74 { 75 ofstream oscore("score.txt"); 76 iscore.open("score.txt"); 77 } 78 getline(iscore, out); 79 char score[10]; 80 char highlyscore[100]; 81 int sum=0; 82 setbkcolor(rgb(244, 215, 215)); 83 cleardevice(); 84 settextcolor(white);//设置文字颜色 85 settextstyle(35, 0, "楷体");//设置文字格式 86 outtextxy(50, 10, "2048游戏"); 87 settextcolor(yellow);//设置文字颜色 88 settextstyle(25, 0, "楷体");//设置文字格式 89 for (int i = 0; i < 4; i++)//计算分数 90 { 91 for (int j = 0; j < 4; j++) 92 { 93 if (map[i][j]>4) 94 { 95 sum += map[i][j] * sqrt(map[i][j]); 96 } 97 } 98 } 99 sprintf(score, "分数:%d", sum); 100 outtextxy(10, 300,score); 101 for (int i = 0; i < out.length(); i++) 102 { 103 highlyscore[i] = out[i]; 104 } 105 stringstream mid; 106 mid << out; 107 mid >> histryhighlyscore; 108 if (histryhighlyscore>sum) 109 { 110 highlyscore[out.length()] = '\0'; 111 settextcolor(red);//设置文字颜色 112 settextstyle(25, 0, "楷体");//设置文字格式 113 outtextxy(10, 330, "历史最高:"); 114 outtextxy(130, 330, highlyscore); 115 } 116 else 117 { 118 char score1[20]; 119 settextcolor(red);//设置文字颜色 120 settextstyle(25, 0, "楷体");//设置文字格式 121 sprintf(score1, "历史最高:%d", sum); 122 outtextxy(10, 330,score1); 123 ofstream oscore1; 124 oscore1.open("score.txt"); 125 oscore1<<sum; 126 oscore1.close(); 127 } 128 iscore.close(); 129 //根据二维数组去画图 130 int x, y, k; 131 for (int i = 0; i < 4; i++) 132 { 133 for (int j = 0; j < 4; j++) 134 { 135 x = 60 * j; 136 y = 60 * i + 55; 137 for ( k = 0; k < 12; k++) 138 { 139 if (imageindex[k] == map[i][j]) 140 { 141 break; 142 } 143 } 144 putimage(x,y,image+k); 145 } 146 } 147 isover = true; 148 } 149 150 //随机产生2或者4; 151 void randintnum() 152 { 153 bool haszero = false; 154 bool isok=false; 155 srand((unsigned)time(null)); //随机函数种子 156 for (int i = 0; i < 4; i++) 157 { 158 for (int j = 0; j < 4; j++) 159 { 160 if (map[i][j] == 0) 161 { 162 haszero = true; 163 map[i][j] = (rand() % 3) * 2; 164 if (map[i][j] == 0) 165 { 166 continue; 167 } 168 isok = true; 169 break; 170 } 171 } 172 if (isok) 173 { 174 break; 175 } 176 } 177 if (!isok) 178 { 179 isok = false; 180 if (haszero) 181 { 182 for (int i = 0; i < 4; i++) 183 { 184 for (int j = 0; j < 4; j++) 185 { 186 if (map[i][j] == 0) 187 { 188 map[i][j] = 2; 189 isok = true; 190 break; 191 } 192 } 193 if (isok) 194 { 195 break; 196 } 197 } 198 } 199 } 200 for (int i = 0; i < 4; i++)//检测最后一步是否留有空位,若全满游戏结束 201 { 202 for (int j = 0; j < 4; j++) 203 { 204 if (map[i][j] == 0) 205 { 206 drawmap(); 207 return; 208 } 209 } 210 } 211 for (int i = 0; i < 4; i++)//游戏失败则重置 212 { 213 for (int j = 0; j < 4; j++) 214 { 215 if (i==0&&j==0) 216 { 217 map[i][j] = 2; 218 continue; 219 } 220 map[i][j] = 0; 221 } 222 } 223 drawmap(); 224 } 225 226 //按键响应 227 void keydownanddraw() 228 { 229 while (true) 230 { 231 char key = _getch();//接收用户按键 232 if (isover) 233 { 234 isover = false; 235 switch (key) 236 { 237 case 'w': 238 case'w': 239 case 72: 240 changeonkeydown(up); 241 break; 242 case 's': 243 case's': 244 case 80: 245 changeonkeydown(down); 246 break; 247 case 'a': 248 case'a': 249 case 75: 250 changeonkeydown(left); 251 break; 252 case 'd': 253 case'd': 254 case 77: 255 changeonkeydown(right); 256 break; 257 default: 258 isover = true; 259 break; 260 } 261 } 262 } 263 } 264 void changeonkeydown(direction direction) 265 { 266 int map[4][4] = { 0 }; 267 bool canmove; 268 switch (direction)//将所有方向改为向左方向,并利用向左算法计算各个方向 269 { 270 case up: 271 for (int i = 0; i < 4; i++) 272 { 273 for (int j = 0; j < 4; j++) 274 { 275 map[j][i] = map[i][j]; 276 } 277 } 278 break; 279 case down: 280 for (int i = 0; i < 4; i++) 281 { 282 for (int j = 0; j < 4; j++) 283 { 284 map[j][3-i] = map[i][j]; 285 } 286 } 287 break; 288 case left: 289 for (int i = 0; i < 4; i++) 290 { 291 for (int j = 0; j < 4; j++) 292 { 293 map[i][j] = map[i][j]; 294 } 295 } 296 break; 297 case right: 298 for (int i = 0; i < 4; i++) 299 { 300 for (int j = 0; j < 4; j++) 301 { 302 map[i][3-j] = map[i][j]; 303 } 304 } 305 break; 306 default: 307 break; 308 } 309 //向左算法 310 canmove=turnleft(map); 311 //将向左改回各自方向 312 switch (direction) 313 { 314 case up: 315 for (int i = 0; i < 4; i++) 316 { 317 for (int j = 0; j < 4; j++) 318 { 319 map[j][i] =map[i][j]; 320 } 321 } 322 break; 323 case down: 324 for (int i = 0; i < 4; i++) 325 { 326 for (int j = 0; j < 4; j++) 327 { 328 map[3-j][i] = map[i][j]; 329 } 330 } 331 break; 332 case left: 333 for (int i = 0; i < 4; i++) 334 { 335 for (int j = 0; j < 4; j++) 336 { 337 map[i][j] = map[i][j]; 338 } 339 } 340 break; 341 case right: 342 for (int i = 0; i < 4; i++) 343 { 344 for (int j = 0; j < 4; j++) 345 { 346 map[i][3-j] = map[i][j]; 347 } 348 } 349 break; 350 default: 351 break; 352 } 353 if (canmove) 354 { 355 randintnum(); 356 drawmap(); 357 } 358 else 359 { 360 isover = true; 361 } 362 }; 363 //算法 364 bool turnleft(int map[4][4])//按向左键进行合并 365 { 366 int k; 367 int len; 368 int save[4]; 369 int move[4][4]; 370 bool canmove = false; 371 372 for (int i = 0; i < 4; i++) 373 { 374 for (int j = 0; j < 4; j++) 375 { 376 move[i][j] = map[i][j]; 377 } 378 } 379 for (int i = 0; i < 4; i++) 380 { 381 k = 0; 382 len = 0; 383 for (int j = 0; j < 4; j++) 384 { 385 if (map[i][j]==0) 386 { 387 continue; 388 } 389 for (k = j+1; k < 4; k++) 390 { 391 if (map[i][k] != 0 ) 392 { 393 if (map[i][j] == map[i][k]) 394 { 395 map[i][j] *= 2; 396 map[i][k] = 0; 397 } 398 break; 399 } 400 } 401 } 402 for (int j = 0; j < 4; j++) 403 { 404 if (map[i][j]!=0) 405 { 406 save[len]=map[i][j]; 407 len++; 408 } 409 } 410 for (int j = 0; j < 4; j++) 411 { 412 if (j<len) 413 { 414 map[i][j] = save[j]; 415 } 416 else 417 { 418 map[i][j] = 0; 419 } 420 } 421 } 422 for (int i = 0; i < 4; i++) 423 { 424 for (int j = 0; j < 4; j++) 425 { 426 if (move[i][j] != map[i][j]) 427 { 428 canmove = true; 429 }; 430 } 431 } 432 return canmove; 433 }
图形库地址:
上一篇: ConcurrentHashMap
下一篇: 手把手教你使用gogs搭建git私有仓库