【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();    }//主循环结尾}//主函数结尾

这里写图片描述

原创粉丝点击