【unity】8.深度优先搜索

上一篇:【unity】7.自适应按钮大小


修改生成坐标

发现上一篇的自适应尺寸在数目是偶数的情况下,生成出来的格子会偏向一边,对偶数的情况进行了额外处理,修改GameLogic.cs中的InitMines的生成部分如下:
这里有一个坑,在做/2操作时,如果最后结果是int,最好将/2改为*0.5

                int _centerX = (int)(parentButtonPrefab.GetComponent<RectTransform>().rect.width * 0.5);
                int _centerY = (int)(parentButtonPrefab.GetComponent<RectTransform>().rect.height * 0.5);
                //int _buttonSize = (int)(buttonPrefab.GetComponent<RectTransform>().rect.height);
        		int x = (int)(_centerX + (_row - maxRow * 0.5) * _buttonSize);
		        if (x % 2 == 0) { x = x + _buttonSize / 2; }
		        int y = (int)(_centerY + (_col - maxCol * 0.5) * _buttonSize);
		        if (y % 2 == 0) { y = y + _buttonSize / 2; }
                Vector3 _pos = new Vector3(x, y);
                GameObject _button = GameObject.Instantiate(buttonPrefab, _pos, Quaternion.identity, parentButtonPrefab.transform);

让点击过的有雷格子不可再次被点击

ClickMine函数中,判断有雷的位置加入以下内容:

        if (bombList.Contains(_row * maxCol + _col))
        {
            _button.GetComponent<Image>().color = Color.red;
            //将按钮设为不可点击
            _button.GetComponent<Button>().enabled = false;
        }

使用深度优先搜索算法自动蔓延灰色格子

在GameLogic.cs中新增函数DFSEmptyMine,并梳理算法逻辑如下:

  1. 如果点击的是空白格子(即附近雷的数量是0),就遍历空白格子上下左右4个格子中是否还有空白格子
  2. 如果有空白格子,且这个格子未被设为disable,则继续遍历这个格子的上下左右四个格子
  3. 如果这个格子不是空白格子(有雷,或附近雷数量不是0),则停止遍历。其中,如果这个格子是数字格,则显示出来。

新增DFSMine函数,并修改ClickMine函数。为了方便判断row和col是否合法,写了一个新函数IsLegalMine来判断。代码如下:

	//判断格子是否合法
    bool IsLegalMine(int _row, int _col)
    {
        if ((_row < 0) || (_col < 0) || (_row > maxRow - 1) || (_col > maxCol - 1)) { return false; }
        if ((_row * maxCol + _col < 0) || (_row * maxCol + _col > maxRow * maxCol - 1)) { return false; }
        return true;
    }

    void DFSMine(int _row, int _col)
    {
    	//如果行和列非法,直接返回
        if (!IsLegalMine(_row, _col)) { return; }
        GameObject _button = buttonList[_row * maxCol + _col];
        //如果搜索到的格子有雷,直接返回
        if (bombList.Contains(_row * maxCol + _col)) { return; }
        //如果这个格子已经被搜索/点击过,直接返回
        if (_button.GetComponent<Button>().enabled == false) { return; }
        //排除以上可能后,这个格子必然是没有雷的合法格子,将其设为不可点击
        _button.GetComponent<Button>().enabled = false;
        int _aroundBombNumber = GetAroundBombNumber(_row, _col);
        if (_aroundBombNumber > 0)
        {
        	//如果附近有雷,显示雷数量,返回
            _button.GetComponentInChildren<TextMeshProUGUI>().text = _aroundBombNumber.ToString();
            return;
        }
        else
        {
        	//如果附近没有雷,将格子置为灰色,搜索上下左右四个格子
            _button.GetComponent<Image>().color = Color.gray;
            DFSMine(_row, _col - 1);
            DFSMine(_row, _col + 1);
            DFSMine(_row - 1, _col);
            DFSMine(_row + 1, _col);
        }
    }

    private void ClickMine(GameObject _button)
    {
        int _row = _button.GetComponent<MinesweeperButton>().GetRow();
        int _col = _button.GetComponent<MinesweeperButton>().GetCol();
        if (bombList.Contains(_row * maxCol + _col))
        {
        	//如果有雷,设为红色并将其设为不可点击
            _button.GetComponent<Image>().color = Color.red;
            _button.GetComponent<Button>().enabled = false;
        }
        else
        {
        	//如果没有雷,直接进行DFS
            DFSMine(_row, _col);
        }
    }

运行结果

运行结果如下
在这里插入图片描述


下一篇:【unity】9.右键单击添加旗子(Button Right Click事件)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值