使用WPF教你一步一步实现连连看(二)_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > 使用WPF教你一步一步实现连连看(二)

使用WPF教你一步一步实现连连看(二)

 2013/7/18 15:18:47  幕三少  博客园  我要评论(0)
  • 摘要:连连看算法第一步:我们考虑在同行或者同列的情况:同行或者同列又分三种情况:第一:边线,RowNum或者ColNum等于0或者9第二:两个相邻第三:同行不相邻,这种事有条件的,所在行(或列)的上下(或左右)紧邻行必须在两个按钮之间已全部消除?好,有出问题了,怎么根据已知的行和列,获取Button是否被消除呢?我们可以定义一个Button的二维数组。并在初始化的时候给它赋值MyButton[,]maps=newMyButton[10,10];maps[i,j]=btn;好
  • 标签:实现 使用 教你

连连看算法


第一步:我们考虑在同行或者同列的情况:

同行或者同列又分三种情况:
  第一:边线,RowNum或者ColNum等于0或者9


  第二:两个相邻

  第三:同行不相邻,这种事有条件的,所在行(或列)的上下(或左右)紧邻行必须在两个按钮之间已全部消除?好,有出问题了,怎么根据已知的行和列,获取Button是否被消除呢?我们可以
定义一个Button的二维数组。并在初始化的时候给它赋值

MyButton[,] maps=new MyButton[10,10];

maps[i, j] = btn;
好,怎么获取Button是否隐藏已经解决。

同行步相邻的又分是从上侧、右侧和中间连。

  第二步:既不同行又不同列的要考虑的更多,东西南北都要考虑到了,而连连看的规则是最多转两个弯,
好了不说了直接上代码了:算法可以自己慢慢琢磨(如果想要最优算法你可以考虑研究下最短路径算法)

   private bool Check(MyButton btn1, MyButton btn2)
        {
            for (int c = 0; c < 10; c++)
            {
                if (c != btn1.ColNum && !(btn1.RowNum == btn2.RowNum && btn1.ColNum == c) && maps[btn1.RowNum, c].Visibility == Visibility.Visible)   //不为A和B的障碍
                    continue;
                if (!IsLine(btn1.RowNum, btn2.RowNum, btn1.RowNum, c))  //Aa
                    continue;
                for (int c2 = 0; c2 < 10; c2++)
                {
                    if (c2 != btn2.ColNum && !(btn1.RowNum == btn2.RowNum && btn1.ColNum == c2) && maps[btn2.RowNum, c2].Visibility == Visibility.Visible)
                        continue;
                    if (!IsLine(btn1.RowNum, c, btn1.RowNum, c2))   //ab
                        continue;
                    if (!IsLine(btn2.RowNum, c2, btn2.RowNum, btn2.ColNum)) //bB
                        continue;
                    return true;
                }
                for (int r = 0; r < 10; r++)
                {
                    if (r != btn2.RowNum && !(r == btn1.RowNum && btn2.ColNum == btn1.ColNum) && maps[r, btn2.ColNum].Visibility == Visibility.Visible)
                        continue;
                    if (!IsLine(btn1.RowNum, c, r, btn2.ColNum))    //ab
                        continue;
                    if (!IsLine(r, btn2.ColNum, btn2.RowNum, btn2.ColNum))  //bB
                        continue;
                    return true;
                }
            }
            for (int r = 0; r < 10; r++)
            {
                if (r != btn1.RowNum && !(r == btn2.RowNum && btn1.ColNum == btn2.ColNum) && maps[r, btn1.RowNum].Visibility == Visibility.Visible)   //不为A和B的障碍
                    continue;
                if (!IsLine(btn1.RowNum, btn1.ColNum, r, btn1.ColNum))  //Aa
                    continue;
                for (int c2 = 0; c2 < 10; c2++)
                {
                    if (c2 != btn2.ColNum && maps[btn2.RowNum, c2].Visibility == Visibility.Visible)
                        continue;
                    if (!IsLine(r, btn1.RowNum, btn2.RowNum, c2))   //ab
                        continue;
                    if (!IsLine(btn2.RowNum, c2, btn2.RowNum, btn2.ColNum)) //bB
                        continue;
                    return true;
                }
                for (int r2 = 0; r2 < 10; r2++)
                {
                    if (r2 != btn2.RowNum && !(r2 == btn1.RowNum && btn2.ColNum == btn1.ColNum) && maps[r2, btn2.ColNum].Visibility == Visibility.Visible)
                        continue;
                    if (!IsLine(r, btn1.ColNum, r2, btn2.ColNum))    //ab
                        continue;
                    if (!IsLine(r2, btn2.ColNum, btn2.RowNum, btn2.ColNum))  //bB
                        continue;
                    return true;
                }
            }
            return false;
        }
        private bool IsLine(int r1, int c1, int r2, int c2)
        {
            int max, min;
            if (r1 == r2)   //同行
            {
                max = ((c1 > c2) ? c1 : c2) - 1;
                min = ((c1 > c2) ? c2 : c1) + 1;
                while (min <= max)
                {
                    if (maps[r1, min].Visibility == Visibility.Visible)
                        return false;
                    min++;
                }
                return true;
            }
            if (c1 == c2)   //同列
            {
                max = ((r1 > r2) ? r1 : r2) - 1;
                min = ((r1 > r2) ? r2 : r1) + 1;
                while (min <= max)
                {
                    if (maps[min, c1].Visibility == Visibility.Visible)
                        return false;
                    min++;
                }
                return true;
            }
            return false;
        }

 


第三步:上面我们完成了算法,也就是我们基本可以玩了。但是玩的过程我们又发现新问题

我们没有保证每个图像都是偶数个,如图:


这个问题要从初始化的时候着手,我们现在要做一百个背景,那么我们先做50个,然后再分别从这个50个中取出

代码如下:

  

   public List<int> Get()
        {
            Random rand = new Random();
            List<int> ran = new List<int>();
            for (int n = 0; n < 50; n++)
                ran.Add(rand.Next(1, 10));
            for (int i = 1; i < 50; i++)
            {
                List<int> temp = new List<int>();
                temp.AddRange(ran);
                for (int n = 0; n < 50; n++)
                {
                    int r = rand.Next(0, temp.Count);
                    ran.Insert(rand.Next(0, ran.Count), temp[r]);
                    temp.RemoveAt(r);
                }
            }

            return ran;
        }

这种思路应该是对的,但是没有达到预期的效果,还是会有剩下,由于缺少时间,可能要过一段时间来弄这个,有

看出问题的高手可以帮我留言,我会争取早点解决问题的。

  我下一步准备是将动画连线与倒计时加上,这可能要等一段时间了。下面是我在网上找的一段练练看算法,希望

能给大家一个参考:

public class LineCore

{

    //整体宽度

    public int width { get; set; }

    //整体高度

    public int height { get; set; }

    //前次被点击的图片

    public Position lastPicture { get; set; }

    //当前被电击的图片

    public Position currentPicture { get; set; }

    // 图片矩阵,-1表示没有图片,初始化时,任意matrix[x,y]当x==0或y==0时,matrix[x,y]=-1

    public int[,] matrix { get; set; }



    public bool testLine(Position current)

    {

        //上次连接成功后,第一次点击,

        if (currentPicture == null)

        {

            currentPicture = current;

            return false;

        }

        //连续点击了同一幅图片

        if (currentPicture.x==current.x&&currentPicture.y==current.y)

        {

            return false;

        }

        //不是相同的图像,不能消除

        if (current.picture != currentPicture.picture)

        {

            lastPicture = null;

            currentPicture = current;

            return false;

        }

        lastPicture = currentPicture;

        currentPicture = current;

        //记录连接路径

        List<Position> paths = new List<Position>();

        paths.Add(currentPicture);

        bool finded=false;

        //向东搜索

        finded = _find(paths, 2, Direct.East, lastPicture);

        if (finded)

        {

            return true;

        }

        //向南搜索

        finded = _find(paths, 2, Direct.South, lastPicture);

        if (finded)

        {

            return true;

        }

        //向西搜索

        finded = _find(paths, 2, Direct.West, lastPicture);

        if (finded)

        {

            return true;

        }

        //向北搜索

        finded = _find(paths, 2, Direct.North, lastPicture);

        if (finded)

        {

            return true;

        }

        //搜索失败

        return false;

    }

    /***

     * results-> 搜索路径

     * chance-> 还剩有转弯的机会,最多2次

     * direct-> 当前前进的方向

     * target-> 搜索的目标

     * **/

    protected bool _find(List<Position> results, int chance, Direct direct, Position target)

    {

        //路径中不能为空

        if (results.Count <= 0)

        {

            return false;

        }

        //取路径中最后一个

        Position currentPos = results.ElementAt(results.Count - 1);

        //构造下一个将要检测的路径

        Position nextPos = new Position();

        switch(direct){

            case Direct.East:

                nextPos.x=currentPos.x+1;

                nextPos.y=currentPos.y;

                break;

                case Direct.West:

                nextPos.x=currentPos.x-1;

                nextPos.y=currentPos.y;

                break;

                case Direct.South:

                nextPos.x=currentPos.x;

                nextPos.y=currentPos.y+1;

                break;

                case Direct.North:

                nextPos.x=currentPos.x;

                nextPos.y=currentPos.y-1;

                break;

        }

        bool overFlow = false;

        //检测是否已经走出边界

        if (nextPos.x < 0 || nextPos.x >= width || nextPos.y < 0 || nextPos.y>=height)

        {

            overFlow = true;

        }

        if (overFlow)

        {

            return false;

        }

        //检测是否是目标

        if (target.x == nextPos.x&&target.y==nextPos.y)

        {

            results.Add(nextPos);

            return true;

        }

        //不是-1 说明该位置有图片,不能通过

        if (matrix[nextPos.x, nextPos.y]!=-1)

        {

            return false;

        }

        //加入路径

        results.Add(nextPos);

        bool find = false;

        //按照当前方向继续试探

        find = _find(results, chance, direct, target);

        if (find)

        {

            return true;

        }

        //转弯机会已经耗尽

        if (chance <= 0)

        {

            //此路不通,将路径最后一个位置删除

            results.RemoveAt(results.Count - 1);

            return false;

        }

        //当前方向向东,还可以转弯向南,向北继续试探

        if (Direct.East == direct)

        {

            find = _find(results, chance-1, Direct.North, target);

            if (find)

            {

                return true;

            }

            find = _find(results, chance-1, Direct.South, target);

            if (find)

            {

                return true;

            }

            results.RemoveAt(results.Count - 1);

            return false;

        }

        //当前方向向南,还可以转弯向东,向西继续试探

        else if (Direct.South == direct)

        {

            find = _find(results, chance-1, Direct.East, target);

            if (find)

            {

                return true;

            }

            find = _find(results, chance-1, Direct.West, target);

            if (find)

            {

                return true;

            }

            results.RemoveAt(results.Count - 1);

            return false;

        }

        //当前方向向西,还可以转弯向南,向北继续试探

        else if (Direct.West == direct)

        {

            find = _find(results, chance-1, Direct.North, target);

            if (find)

            {

                return true;

            }

            find = _find(results, chance-1, Direct.South, target);

            if (find)

            {

                return true;

            }

            results.RemoveAt(results.Count - 1);

            return false;

        }

        //当前方向向北,还可以转弯向东,向西继续试探

        else

        {

            find = _find(results, chance-1, Direct.East, target);

            if (find)

            {

                return true;

            }

            find = _find(results, chance-1, Direct.West, target);

            if (find)

            {

                return true;

            }

            results.RemoveAt(results.Count - 1);

            return false;

        }

    }

    //联通成功后,将两个位置设置成空

    public void onSuccess()

    {

        this.matrix[this.lastPicture.x, this.lastPicture.y] = -1;

        this.matrix[this.currentPicture.x, this.currentPicture.y] = -1;

        this.currentPicture = null;

        this.lastPicture = null;

    }





}

 

public class Position

{

    public int x { get; set; }

    public int y { get; set; }

    //picture 表示不同图像,如果是-1,表示为空

    public int picture { get; set; }

}



public enum Direct : int

{

    East = 0, South = 1, West = 2, North = 3

   }

请高手多多指正……

发表评论
用户名: 匿名