(dfs)连连看

<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 10

struct 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;                              //第二次点击的Cube
private:
    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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
DFS(Depth First Search,深度优先搜索)是一种搜索算法,用于在树或图等数据结构中遍历所有节点。DFS 从起始节点开始,沿着一条路径一直遍历到底,直到不能再前进为止,然后返回上一个节点,继续遍历其它路径。DFS 可以用递归或栈来实现。 在 DFS 中,我们可以分为两种遍历方式:深度优先遍历(preorder)、后序遍历(postorder)。深度优先遍历从根节点开始,一直遍历到叶子节点,然后返回上一级节点,进行下一轮遍历。后序遍历则是遍历完子节点之后,再遍历父节点。这两种遍历方式都是基于递归实现的。 下面是一个使用递归实现 DFS 的示例代码(以二叉树为例): ```python class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right class Solution: def dfs(self, node: TreeNode): if node is None: return print(node.val) # 先访问根节点 self.dfs(node.left) # 再遍历左子树 self.dfs(node.right) # 最后遍历右子树 def preorderTraversal(self, root: TreeNode) -> List[int]: self.result = [] self.dfs(root) return self.result ``` 在上面的代码中,我们定义了一个 TreeNode 类来表示二叉树中的节点,其中包括节点的值、左子节点和右子节点。我们还定义了一个 Solution 类来实现 DFS 遍历,其中 dfs() 方法用于进行深度优先遍历,preorderTraversal() 方法则是用于求解前序遍历的结果。在 dfs() 方法中,我们先访问根节点,然后再递归遍历左子树和右子树,直到遍历完整棵树。在遍历各个节点的过程中,我们可以将节点的值保存到一个列表中,最后返回即可。 当我们需要使用 DFS 遍历一棵树时,只需要创建一个 Solution 对象,然后调用其对应的方法即可。比如,可以使用如下代码来创建一棵二叉树,然后对其进行 DFS 遍历: ```python root = TreeNode(1) root.left = TreeNode(2) root.right = TreeNode(3) root.left.left = TreeNode(4) root.left.right = TreeNode(5) solution = Solution() result = solution.preorderTraversal(root) print(result) # 输出: [1, 2, 4, 5, 3] ``` 在上面的代码中,我们首先创建了一棵二叉树,然后创建了一个 Solution 对象,最后调用其 preorderTraversal() 方法来进行遍历。遍历完成后,将遍历结果输出即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值