C++实现2048小游戏
2019-09-08 09:35:58来源:博客园 阅读 ()
C++实现2048小游戏
代码如下:
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 }
图形库地址:
https://easyx.cn/downloads/
原文链接:https://www.cnblogs.com/hixingchen/p/11463268.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:矩阵乘法(七):其它一些典型应用
下一篇:C++中的const的简单用法
- C++ 转换函数搭配友元函数 2020-06-10
- C++ 自动转换和强制类型转换(用户自定义类类型) 2020-06-10
- C++ rand函数 2020-06-10
- C++ 友元函数 2020-06-10
- C++ 运算符重载 2020-06-10
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash