【C++】EasyPushBox
来源:互联网 发布:淘宝猫胡子是假货吗 编辑:程序博客网 时间:2024/06/08 04:39
#include <iostream>#include <iomanip> //使用到 setw()#include <conio.h> //使用到 _getch()using namespace std;#pragma region 定义常量const unsigned short MAP_ROW = 8;//行const unsigned short MAP_COLUMN = 8;//列const unsigned short NUL = 0;//空地const unsigned short WALL = 1;//墙const unsigned short GRASS = 2;//草地const unsigned short BOX = 3;//箱子const unsigned short PLAYER = 4;//玩家const unsigned short FINAL = 5;//终点const char* STRNUL = " ";//空地const char* STRWALL = "口";//墙const char* STRGRASS = "▓";//草地const char* STRBOX = "田";//箱子const char* STRPLAYER = "♀";//玩家const char* STRFINAL = "◎";//终点const int A = 97;//A键const int D = 100;//D键const int W = 119;//W键const int S = 115;//S键const unsigned int MAX_BOX = 5;//最大箱子数量const unsigned int MAX_FINAL = 5;//最大终点数量#pragma endregion#pragma region 全局变量/*玩家坐标*/unsigned int playerX = 1;unsigned int playerY = 1;/*箱子数量*/int box_count = 0;/*箱子编号*/int box_SerialNumber = 0;/*终点的坐标数组*/unsigned int finals[MAX_FINAL * 2];/*箱子的坐标数组*/unsigned int boxes[MAX_BOX * 2];/*游戏是否胜利*/bool isWin = false;/*游戏是否失败*/bool isDefeat = false;#pragma endregion#pragma region 地图数据unsigned short MapData[MAP_ROW][MAP_COLUMN] ={ { 1, 1, 1, 1, 1, 1, 1, 1 }, { 1, 4, 0, 0, 0, 0, 5, 1 }, { 1, 0, 0, 0, 3, 0, 0, 1 }, { 1, 0, 0, 1, 2, 0, 0, 1 }, { 1, 0, 3, 0, 2, 0, 0, 1 }, { 1, 3, 0, 0, 5, 0, 0, 1 }, { 1, 5, 0, 0, 0, 0, 0, 1 }, { 1, 1, 1, 1, 1, 1, 1, 1 }};#pragma endregion/*某位置是否为终点*/bool IsFinal(unsigned int x, unsigned int y){ for (int i = 0; i < box_count; i++) { if (x == finals[i * 2] && y == finals[i * 2 + 1]) return true; } return false;}/*判断某个位置是否是箱子*/bool IsBox(unsigned int x, unsigned int y, int& position){ for (int i = 0; i < box_count; ++i) { if (x == boxes[i * 2] && y == boxes[i * 2 + 1]) { position = i; return true; } } return false;}/*判断某个位置是否是墙*/bool IsWall(unsigned int x, unsigned int y){ return MapData[y][x] == WALL;}/*判断某个位置是否是草*/bool IsGrass(unsigned int x, unsigned int y){ return MapData[y][x] == GRASS;}/*判断某个位置是否是障碍*/bool IsBlock(unsigned int x, unsigned int y){ return IsGrass(x, y) || IsWall(x, y);}/*判断当前箱子位置是否位于边界*/bool IsBoxAtBound(unsigned int bx, unsigned int by){ return bx == 1 || bx == MAP_COLUMN - 2 || by == 1 || by == MAP_ROW - 2;}/*判断当前箱子位置是否位于两个障碍组成的拐角*/bool IsBoxAtCorner(unsigned int bx, unsigned int by){ return (IsBlock(bx - 1, by) || IsBlock(bx + 1, by)) && (IsBlock(bx, by - 1) || IsBlock(bx, by + 1));}/*打印游戏标题*/void PrintTitle(){ cout << "*****************************************" << endl; cout << "* 推箱子重制版 *" << endl; cout << "*****************************************" << endl;}/*打印提示信息*/void PrintTips(){ if (isWin) cout << "恭喜您,游戏胜利" << endl; else if (isDefeat) cout << "胜败乃兵家常事,请大侠重新来过" << endl;}/*根据现有的地图数据转换成相应的表示字符*/const char* Data2Str(unsigned short data){ switch (data) { case NUL: return STRNUL; case WALL: return STRWALL; case GRASS: return STRGRASS; case BOX: return STRBOX; case PLAYER: return STRPLAYER; case FINAL: return STRFINAL; default: return STRNUL; }}/*绘制地图*/void PrintMap(unsigned short mapdata[][MAP_COLUMN]){ for (int i = 0; i < MAP_ROW; i++) { cout << "\t ";//制表符 for (int j = 0; j < MAP_COLUMN; j++) { /*处理地图中出现遮挡的情况: “终点”位置的地图数据不改变,只暂时显示箱子或玩家*/ if (mapdata[i][j] == FINAL) { if (i == playerY&&j == playerX) { cout << setw(2) << STRPLAYER; } else if (IsBox(j,i,box_SerialNumber)) { cout << setw(2) << STRBOX; } else { cout << setw(2) << STRFINAL; } } else { cout << setw(2) << Data2Str(mapdata[i][j]); } } cout << endl; }}/*改变地图数据,row行col列为data*/void SetMapData(unsigned row, unsigned col, unsigned short data){ MapData[row][col] = data;}/*判断游戏胜利*/bool IsSuccess(unsigned int finals[], unsigned int boxs[], int boxcount){ for (int i = 0; i < boxcount; i++) { //得到box的位置 unsigned tbx = boxs[i * 2]; unsigned tby = boxs[i * 2 + 1]; bool isMatch = false; //是否匹配标志位 for (int j = 0; j < boxcount; j++) { unsigned tfx = finals[j * 2]; unsigned tfy = finals[j * 2 + 1]; if (tbx == tfx && tby == tfy) isMatch = true; } if (!isMatch) { return false; //有一个没有匹配视为还未胜利 } } return true; //全部匹配即为 }/*找出玩家在地图中的位置*/void FindPlayer(unsigned short mapdata[][MAP_COLUMN]){ for (int i = 0; i < MAP_ROW; i++) { for (int j = 0; j < MAP_COLUMN; j++) { if (mapdata[i][j] == PLAYER) { playerX = j; playerY = i; break; } } }}/*找出终点在地图中的位置*/void FindFinal(unsigned short mapdata[][MAP_COLUMN]){ int index = 0; for (int i = 0; i < MAP_ROW; i++) { for (int j = 0; j < MAP_COLUMN; j++) { if (mapdata[i][j] == FINAL) { finals[index++] = j; finals[index++] = i; } } }}/*找出箱子在地图中的位置*/void FindBox(unsigned short mapdata[][MAP_COLUMN]){ int index = 0; for (int i = 0; i < MAP_ROW; i++) { for (int j = 0; j < MAP_COLUMN; j++) { if (mapdata[i][j] == BOX) { boxes[index++] = j; boxes[index++] = i; } } } box_count = index / 2;}/*玩家移动*/void MovePlayer(int dx, int dy){ playerX += dx; playerY += dy;}/*箱子移动*/bool MoveBox(unsigned int& bx, unsigned int& by, int dx, int dy){ /*判断将要移动到的位置是否有障碍物或者另一个箱子*/ if (IsBlock(bx + dx, by + dy) || IsBox(bx + dx, by + dy, box_SerialNumber)) return false; /*将之前的箱子在地图中的坐标位置的数据置为NUL,使其显示为空地*/ if (!IsFinal(bx, by)) { SetMapData(by, bx, NUL); } /*移动箱子,修改箱子数组中的数据*/ bx += dx; by += dy; /*判定是否胜利*/ if (IsSuccess(finals, boxes, box_count)) isWin = true; /*判定是否失败*/ else if (IsBoxAtCorner(bx, by) && !IsFinal(bx, by)) isDefeat = true; //todo... /*根据当前箱子的坐标信息,修改地图中箱子的数据*/ if (!IsFinal(bx, by)) { SetMapData(by, bx, BOX); } return true;}void main(){ /*打印游戏标题*/ PrintTitle(); /*绘制地图*/ PrintMap(MapData); /*找到玩家坐标*/ FindPlayer(MapData); /*找到终点坐标*/ FindFinal(MapData); /*找到箱子坐标*/ FindBox(MapData); /*游戏主循环*/ int code; //按键输入返回值 while ((code = _getch()) && !isWin && !isDefeat) { /*按键处理*/ switch (code) { case A: /*如果第一帧或上一帧玩家坐标没有与终点坐标重合, 将上一帧玩家所在坐标的数据置NUL*/ if (!IsFinal(playerX, playerY)) { SetMapData(playerY, playerX, NUL); } /*修改玩家坐标数组中的数据*/ MovePlayer(-1, 0); /*障碍物判定*/ if (IsBlock(playerX, playerY)) MovePlayer(1, 0); /*箱子判定*/ else if (IsBox(playerX, playerY, box_SerialNumber)) { if (!MoveBox(boxes[box_SerialNumber * 2], boxes[box_SerialNumber * 2 + 1], -1, 0)) MovePlayer(1, 0); } /*终点判定,若不是终点,改变地图数据*/ if (!IsFinal(playerX, playerY)) SetMapData(playerY, playerX, PLAYER); break; case D: if (!IsFinal(playerX, playerY)) SetMapData(playerY, playerX, NUL); MovePlayer(1, 0); if (IsBlock(playerX, playerY)) MovePlayer(-1, 0); else if (IsBox(playerX, playerY, box_SerialNumber)) { if (!MoveBox(boxes[box_SerialNumber * 2], boxes[box_SerialNumber * 2 + 1], 1, 0)) MovePlayer(-1, 0); } if (!IsFinal(playerX, playerY)) SetMapData(playerY, playerX, PLAYER); break; case W: if (!IsFinal(playerX, playerY)) SetMapData(playerY, playerX, NUL); MovePlayer(0, -1); if (IsBlock(playerX, playerY)) MovePlayer(0, 1); else if (IsBox(playerX, playerY, box_SerialNumber)) { if (!MoveBox(boxes[box_SerialNumber * 2], boxes[box_SerialNumber * 2 + 1], 0, -1)) MovePlayer(0, 1); } if (!IsFinal(playerX, playerY)) SetMapData(playerY, playerX, PLAYER); break; case S: if (!IsFinal(playerX, playerY)) SetMapData(playerY, playerX, NUL); MovePlayer(0, 1); if (IsBlock(playerX, playerY)) MovePlayer(0, -1); else if (IsBox(playerX, playerY, box_SerialNumber)) { if (!MoveBox(boxes[box_SerialNumber * 2], boxes[box_SerialNumber * 2 + 1], 0, 1)) MovePlayer(0, -1); } if (!IsFinal(playerX, playerY)) SetMapData(playerY, playerX, PLAYER); break; default: break; }//按键处理结尾 /*清屏操作*/ system("cls"); /*打印游戏标题*/ PrintTitle(); /*绘制地图*/ PrintMap(MapData); /*打印提示信息*/ PrintTips(); }//主循环结尾}//主函数结尾
阅读全文
0 0
- 【C++】EasyPushBox
- c
- c
- c
- c
- C
- c
- c
- c
- C+
- c
- C
- c
- c
- c
- C
- C
- c
- 自执行函数
- Apache按日期切割访问日志
- C++字符串分割和C语言常用格式控制
- 小白学Git(2)——Git管理修改
- QT中多线程,函数无法执行的问题
- 【C++】EasyPushBox
- 【编译原理】LL(1)文法分析全过程(FIRST/FLLOW/SELECT集等)实现(c++语言)
- 第十三周【项目1
- Java并发编程札记-(三)JUC原子类-03原子方式更新数组
- 学习记录
- 并查集解决朋友圈问题
- bzoj3224 Tyvj 1728 普通平衡树(splay/treap)
- 【Codevs1074】 食物链 并查集 平行世界 (6/1000)
- MySQL常用命令