回溯法实现连连看

来源:互联网 发布:ios去广告软件 编辑:程序博客网 时间:2024/05/20 09:45

<1>Cube.h

#ifndef __JNTest__Cube__#define __JNTest__Cube__#include "cocos2d.h"USING_NS_CC;typedef enum CubeType{    CubeType_Red,     //红    CubeType_Blue,    //蓝    CubeType_White,   //白    CubeType_Green,   //绿    CubeType_Yellow,  //黄    CubeType_Count}CubeType;class Cube : public Node{public:    Cube();    ~Cube();    bool init(CubeType cubeType, int row, int col);    static Cube* create(CubeType cubeType, int row, int col);    Rect getCubeBoundingBox();private:    CC_SYNTHESIZE(int, _row, Row);    CC_SYNTHESIZE(int, _col, Col);    CC_SYNTHESIZE(CubeType, _cubeType, CubeType);                   //方块数字    CC_SYNTHESIZE(LayerColor*, _bgLayerColor, BgLayerColor);                     //背景颜色};#endif /* defined(__JNTest__Cube__) */
<2>Cube.cpp

#include "Cube.h"Cube::Cube(): _bgLayerColor(NULL){    }Cube::~Cube(){    }bool Cube::init(CubeType cubeType, int row, int col){        _row = row;    _col = col;    _cubeType = cubeType;        Color4B color;        switch (cubeType) {        case CubeType_Red:            color = Color4B::RED;            break;        case CubeType_Blue:            color = Color4B::BLUE;            break;        case CubeType_White:            color = Color4B::WHITE;            break;        case CubeType_Green:            color = Color4B::GREEN;            break;        case CubeType_Yellow:            color = Color4B::YELLOW;            break;    }        //背景颜色    _bgLayerColor = LayerColor::create(color, 60, 90);    _bgLayerColor->ignoreAnchorPointForPosition(false);    this->addChild(_bgLayerColor);        return true;}Cube* Cube::create(CubeType cubeType, int row, int col){        Cube* cube = new Cube();        if(cube && cube->init(cubeType, row, col)){        cube->autorelease();        return cube;    }    CC_SAFE_DELETE(cube);    return NULL;}Rect Cube::getCubeBoundingBox(){    Rect rect;        Vec2 pt = this->getPosition();        rect.size.width = 60;    rect.size.height = 90;    rect.origin.x = pt.x - 30;    rect.origin.y = pt.y - 45;        return rect;}
<3>GameScene.h

#ifndef __JNTest__GameScene__#define __JNTest__GameScene__#include "cocos2d.h"USING_NS_CC;#include "Cube.h"#include <vector>using namespace std;#define MAP_WIDTH 10#define MAP_HEIGHT 10struct PT{    PT(int row, int col):_row(row), _col(col){}    PT&  operator = (const PT& other){        this->_row = other._row;        this->_col = other._col;        return *this;    }        bool operator == (const PT& other){        return this->_row == other._row && this->_col == other._col;    }        int _row;    int _col;};class GameScene : public Layer{public:    GameScene();    ~GameScene();    static Scene* scene();    virtual bool init();    CREATE_FUNC(GameScene);public:    bool onTouchBegan(Touch *touch, Event *unused);      //触摸        Vec2 getPositionByRowAndCol(int row, int col);       //根据行列得到方块应该摆放的位置    Cube* getClickCubeByPoint(Vec2 clickPoint);          //根据点击点获取点击到的方块    Cube* getCubeByPT(const PT& pt);                     //根据行列获取方块        void judgeTwoCube(Cube* cube1, Cube* cube2);         //判断2个方块是否相同    void findPath(PT ptBegin, PT ptEnd, int turns, vector<PT> ptVecPath, vector<PT>& bestVecPath);  //回溯法查找路径        bool isTurn(const vector<PT>& vectPath, const PT& ptNow); //是否有拐点        void removeTwoCube(Cube* cube1, Cube* cube2);        //移除2个方块        void tipNode(Node* node);                            //在方块上添加闪烁提示    void removeTipNode(Node* node);                      //移除提示    bool isNear(Cube* cube1, Cube* cube2);               //两个方块是否是相邻    void printDepth(vector<PT>& vecPath);                //打印vector中的路径信息    PT findOneKongPT();                                  //返回一个空位置的PT    bool isGameOver();                                   //游戏是否结束    Cube* _firstClickCube;                               //第一次点击的Cube    Cube* _secondClickCube;                              //第二次点击的Cubeprivate:    Cube** _matrixCube;};#endif /* defined(__JNTest__GameScene__) */
<4>GameScene.cpp

#include "GameScene.h"//上下左右四个方向PT dir[4] = {    {1, 0},    {-1, 0},    {0, -1},    {0, 1}};//是否访问过bool vis[10][10] = {0};//设置所有及诶单都没有访问过void setAllNotVisit(){    for(int i = 0; i < 10; i++)        for(int j = 0; j < 10; j++){            vis[i][j] = false;        }}GameScene::GameScene():_firstClickCube(NULL), _secondClickCube(NULL){    srand((unsigned)time(NULL));}GameScene::~GameScene(){    }Scene* GameScene::scene(){    Scene* scene = Scene::create();    GameScene* layer = GameScene::create();    scene->addChild(layer);    return scene;}bool GameScene::init(){    if(!Layer::init()){        return false;    }        EventListenerTouchOneByOne* touchListener = EventListenerTouchOneByOne::create();    touchListener->onTouchBegan = CC_CALLBACK_2(GameScene::onTouchBegan, this);    _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);        int size = sizeof(Cube*) * MAP_WIDTH * MAP_HEIGHT;    _matrixCube = (Cube**)malloc(size);    memset((void*)_matrixCube, 0, size);        //设置所有及诶单都没有访问过    setAllNotVisit();        //初始化地图    PT pt = findOneKongPT();    int row, col;    while(pt._row != -1){                CubeType cubeType = (CubeType)(rand() % CubeType_Count);                row = pt._row;        col = pt._col;                Cube* cube = Cube::create(cubeType, row, col);        cube->setPosition(getPositionByRowAndCol(row, col));        _matrixCube[row * MAP_WIDTH + col] = cube;        this->addChild(cube);                pt = findOneKongPT();                row = pt._row;        col = pt._col;                cube = Cube::create(cubeType, row, col);        cube->setPosition(getPositionByRowAndCol(row, col));        _matrixCube[row * MAP_WIDTH + col] = cube;        this->addChild(cube);                pt = findOneKongPT();    }        return true;}bool GameScene::onTouchBegan(Touch *touch, Event *unused){        Vec2 clickPoint = touch->getLocation();        Cube* clickCube = getClickCubeByPoint(clickPoint);        if(clickCube && !_firstClickCube){        _firstClickCube = clickCube;        tipNode(_firstClickCube);            }else if (clickCube && _firstClickCube && clickCube != _firstClickCube){        _secondClickCube = clickCube;        tipNode(_secondClickCube);        judgeTwoCube(_firstClickCube, _secondClickCube);    }        return true;}Vec2 GameScene::getPositionByRowAndCol(int row, int col){    return Vec2(col * 64 + 32, row * 96 + 48);}Cube* GameScene::getClickCubeByPoint(Vec2 clickPoint){    for(int row = 1; row < MAP_HEIGHT - 1; row++){        for(int col = 1; col < MAP_WIDTH - 1; col++){                        Cube* cube = _matrixCube[row * MAP_WIDTH + col];            if(cube && cube->getCubeBoundingBox().containsPoint(clickPoint)){                return cube;            }        }    }    return NULL;}Cube* GameScene::getCubeByPT(const PT& pt){    return _matrixCube[pt._row * MAP_WIDTH + pt._col];}void GameScene::judgeTwoCube(Cube* cube1, Cube* cube2) {    removeTipNode(_firstClickCube);    removeTipNode(_secondClickCube);        _firstClickCube = NULL;    _secondClickCube = NULL;        if(cube1->getCubeType() != cube2->getCubeType()){        return;    }        vector<PT> ptVec;    ptVec.push_back(PT(cube1->getRow(), cube1->getCol())); //把当前的节点添加进来            vector<PT> bestPath = ptVec;    findPath(PT(cube1->getRow(), cube1->getCol()), PT(cube2->getRow(), cube2->getCol()), 0, ptVec, bestPath);    printDepth(bestPath);        if(bestPath.size() > 1){        removeTwoCube(cube1, cube2);    }        if(isGameOver()){        Director::getInstance()->replaceScene(TransitionFade::create(1.0f, GameScene::scene()));    }}void GameScene::findPath(PT ptBegin, PT ptEnd, int turns, vector<PT> ptVecPath, vector<PT>& bestVecPath){            if(ptBegin == ptEnd && turns <= 2){  //成功        if(ptVecPath.size() < bestVecPath.size() || bestVecPath.size() == 1){            bestVecPath = ptVecPath;        }        return;    }        if(ptBegin._row < 0 || ptBegin._col < 0 || ptBegin._row > MAP_WIDTH - 1 || ptBegin._col > MAP_HEIGHT || turns > 2){ //失败        return;    }        for(int i = 0; i < 4; i++){  //四个方向查找                int oldRow = ptBegin._row;        int oldCol = ptBegin._col;                int newRow = ptBegin._row + dir[i]._row;        int newCol = ptBegin._col + dir[i]._col;                        if(!vis[newRow][newCol]  && (!getCubeByPT(PT(newRow, newCol)) || PT(newRow, newCol) == ptEnd)){                                    vis[newRow][newCol] = true;            ptBegin = PT(newRow, newCol);                        ptVecPath.push_back(ptBegin);                        if(isTurn(ptVecPath, ptBegin)){                turns = turns + 1;            }                        findPath(ptBegin, ptEnd, turns, ptVecPath, bestVecPath);                        if(isTurn(ptVecPath, ptBegin)){                turns = turns - 1;            }                        ptVecPath.pop_back();                        ptBegin = PT(oldRow, oldCol);            vis[newRow][newCol] = false;                    }    }}bool GameScene::isTurn(const vector<PT>& vecPath, const PT& ptNow){        if(vecPath.size() < 3){        return false;    }        PT ptPrevious = vecPath[vecPath.size() - 3];        if(ptPrevious._row != ptNow._row && ptPrevious._col != ptNow._col){        return true;    }        return false;}void GameScene::removeTwoCube(Cube* cube1, Cube* cube2){        _matrixCube[cube1->getRow() * MAP_WIDTH + cube1->getCol()] = NULL;    cube1->removeFromParent();    cube1 = NULL;        _matrixCube[cube2->getRow() * MAP_WIDTH + cube2->getCol()] = NULL;    cube2->removeFromParent();    cube2 = NULL;}void GameScene::tipNode(Node* node){    Sequence* seq = Sequence::create(ScaleTo::create(0.5f, 0.8f), ScaleTo::create(0.8f, 1.2f), ScaleTo::create(0.4f, 1.0f), NULL);    RepeatForever* repeat = RepeatForever::create(seq);    node->runAction(repeat);}void GameScene::removeTipNode(Node* node){    node->setScale(1.0f);    node->stopAllActions();}bool GameScene::isNear(Cube* cube1, Cube* cube2){        if(abs(cube1->getRow() - cube2->getRow()) == 1 && cube1->getCol() == cube2->getCol()){        return true;    }        if(abs(cube1->getCol() - cube2->getCol()) == 1 && cube1->getRow() == cube2->getRow()){        return true;    }        return false;}void GameScene::printDepth(vector<PT>& vecPath){        do{        if(vecPath.size() == 1){            break;        }                for(vector<PT>::iterator iter = vecPath.begin(); iter != vecPath.end(); iter++){                        PT pt = (*iter);                        Sequence* seq = Sequence::create(Blink::create(1.2f, 4), RemoveSelf::create(), NULL); //                        Label* labTip = Label::createWithSystemFont("*", "Arial", 80);            labTip->ignoreAnchorPointForPosition(false);            labTip->setPosition(getPositionByRowAndCol(pt._row, pt._col));            this->addChild(labTip);            labTip->runAction(seq);                    }            }while (0);}PT GameScene::findOneKongPT(){        vector<PT> vPt;        for(int row = 1; row < MAP_HEIGHT - 1; row++){        for(int col = 1; col < MAP_WIDTH - 1; col++){                        Cube* cube = _matrixCube[row * MAP_WIDTH + col];            if(cube){                continue;            }            vPt.push_back(PT(row, col));        }    }        if(vPt.size() == 0){        return PT(-1, -1);    }        return vPt[rand() % (vPt.size())];}bool GameScene::isGameOver(){    for(int row = 1; row < MAP_HEIGHT - 1; row++){        for(int col = 1; col < MAP_WIDTH - 1; col++){                        Cube* cube = _matrixCube[row * MAP_WIDTH + col];            if(cube){  //如果还有方块没有消除,则游戏就没有结束.                return false;            }        }    }    return true;}

0 0
原创粉丝点击