连连看算法

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

同行或者同列又分三种情况:
  第一:边线,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 = ; c < ; 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 = ; c2 < ; 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 = ; r < ; 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 = ; r < ; 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 = ; c2 < ; 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 = ; r2 < ; 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) - ;
min = ((c1 > c2) ? c2 : c1) + ;
while (min <= max)
{
if (maps[r1, min].Visibility == Visibility.Visible)
return false;
min++;
}
return true;
}
if (c1 == c2) //同列
{
max = ((r1 > r2) ? r1 : r2) - ;
min = ((r1 > r2) ? r2 : r1) + ;
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 = ; n < ; n++)
ran.Add(rand.Next(, ));
for (int i = ; i < ; i++)
{
List<int> temp = new List<int>();
temp.AddRange(ran);
for (int n = ; n < ; n++)
{
int r = rand.Next(, temp.Count);
ran.Insert(rand.Next(, 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, , Direct.East, lastPicture);

        if (finded)

        {

            return true;

        }

        //向南搜索

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

        if (finded)

        {

            return true;

        }

        //向西搜索

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

        if (finded)

        {

            return true;

        }

        //向北搜索

        finded = _find(paths, , 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 <= )

        {

            return false;

        }

        //取路径中最后一个

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

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

        Position nextPos = new Position();

        switch(direct){

            case Direct.East:

                nextPos.x=currentPos.x+;

                nextPos.y=currentPos.y;

                break;

                case Direct.West:

                nextPos.x=currentPos.x-;

                nextPos.y=currentPos.y;

                break;

                case Direct.South:

                nextPos.x=currentPos.x;

                nextPos.y=currentPos.y+;

                break;

                case Direct.North:

                nextPos.x=currentPos.x;

                nextPos.y=currentPos.y-;

                break;

        }

        bool overFlow = false;

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

        if (nextPos.x <  || nextPos.x >= width || nextPos.y <  || 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]!=-)

        {

            return false;

        }

        //加入路径

        results.Add(nextPos);

        bool find = false;

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

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

        if (find)

        {

            return true;

        }

        //转弯机会已经耗尽

        if (chance <= )

        {

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

            results.RemoveAt(results.Count - );

            return false;

        }

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

        if (Direct.East == direct)

        {

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

            if (find)

            {

                return true;

            }

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

            if (find)

            {

                return true;

            }

            results.RemoveAt(results.Count - );

            return false;

        }

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

        else if (Direct.South == direct)

        {

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

            if (find)

            {

                return true;

            }

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

            if (find)

            {

                return true;

            }

            results.RemoveAt(results.Count - );

            return false;

        }

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

        else if (Direct.West == direct)

        {

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

            if (find)

            {

                return true;

            }

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

            if (find)

            {

                return true;

            }

            results.RemoveAt(results.Count - );

            return false;

        }

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

        else

        {

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

            if (find)

            {

                return true;

            }

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

            if (find)

            {

                return true;

            }

            results.RemoveAt(results.Count - );

            return false;

        }

    }

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

    public void onSuccess()

    {

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

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

        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 = , South = , West = , North = 

   }

请高手多多指正……

使用WPF教你一步一步实现连连看(二)的更多相关文章

  1. 使用WPF教你一步一步实现连连看

    使用WPF教你一步一步实现连连看(一) 第一步: 问题,怎样动态的建立一个10*10的grid(布局) for (int i = 0; i < 10; i++){ RowDefinition r ...

  2. 一步一步教你如何在linux下配置apache+tomcat(转)

    一步一步教你如何在linux下配置apache+tomcat   一.安装前准备. 1.   所有组件都安装到/usr/local/e789目录下 2.   解压缩命令:tar —vxzf 文件名(. ...

  3. 一步一步教你将普通的wifi路由器变为智能广告路由器

    一步一步教你将普通的wifi路由器变为智能广告路由器 相信大家对WiFi智能广告路由器已经不再陌生了,现在很多公共WiFi上网,都需要登录并且验证,这也就是WiFi广告路由器的最重要的功能.大致就是下 ...

  4. 一步一步教你使用Git

    一步一步教你使用Git 互联网给我们带来方便的同时,也时常让我们感到困惑.随便搜搜就出一大堆结果,然而总是有大量的重复和错误.小妖发出的内容,都是自己实测过的,有问题请留言. 现在,你已经安装了Git ...

  5. 一步一步教你用 Vue.js + Vuex 制作专门收藏微信公众号的 app

    一步一步教你用 Vue.js + Vuex 制作专门收藏微信公众号的 app 转载 作者:jrainlau 链接:https://segmentfault.com/a/1190000005844155 ...

  6. Ace教你一步一步做Android新闻客户端(一)

    复制粘贴了那么多博文很不好意思没点自己原创的也说不出去,现在写一篇一步一步教你做安卓新闻客户端,借此机会也是让自己把相关的技术再复习一遍,大神莫笑,专门做给新手看. 手里存了两篇,一个包括软件视图 和 ...

  7. 一步一步教你实现iOS音频频谱动画(二)

    如果你想先看看最终效果再决定看不看文章 -> bilibili 示例代码下载 第一篇:一步一步教你实现iOS音频频谱动画(一) 本文是系列文章中的第二篇,上篇讲述了音频播放和频谱数据计算,本篇讲 ...

  8. 一步一步教你实现iOS音频频谱动画(一)

    如果你想先看看最终效果再决定看不看文章 -> bilibili 示例代码下载 第二篇:一步一步教你实现iOS音频频谱动画(二) 基于篇幅考虑,本次教程分为两篇文章,本篇文章主要讲述音频播放和频谱 ...

  9. 通过Dapr实现一个简单的基于.net的微服务电商系统(四)——一步一步教你如何撸Dapr之订阅发布

    之前的章节我们介绍了如何通过dapr发起一个服务调用,相信看过前几章的小伙伴已经对dapr有一个基本的了解了,今天我们来聊一聊dapr的另外一个功能--订阅发布 目录:一.通过Dapr实现一个简单的基 ...

  10. 通过Dapr实现一个简单的基于.net的微服务电商系统(三)——一步一步教你如何撸Dapr

    目录:一.通过Dapr实现一个简单的基于.net的微服务电商系统 二.通过Dapr实现一个简单的基于.net的微服务电商系统(二)--通讯框架讲解 三.通过Dapr实现一个简单的基于.net的微服务电 ...

随机推荐

  1. Azkaban使用安装文档

    Azkaban使用安装文档 Azkaban简介 Azkaban的是什么 Azkaban是由Linkedin公司推出的一个批量工作流任务调度器,用于在一个工作流内以一个特定的顺序运行一组工作和流程.Az ...

  2. Latex 模版生成会议论文 不显示Keywords,而是显示 Index Terms- ,改成Keywords 方法

    一. 不管显示何种内容,TEX 文件都是 \begin{IEEEKeywords} 关键词1.关键词2,..... \end{IEEEKeywords} 其中:模版文件 IEEETran.cls存在下 ...

  3. 5.html基础标签:块级+行级元素+特殊字符+嵌套规则

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. JavaScript在IE和Firefox的不兼容问题解决方法总结

    1.兼容Firefox的 outerHTML,Firefox中没有outerHtml的方法. if (window.HTMLElement) { HTMLElement.prototype.__def ...

  5. Python环境搭建详解(Window平台)

    前言 Python,是一种面向对象的解释型计算机程序设计语言,是纯粹的自由软件,Python语法简洁清晰,特色是强制用空白符作为语句缩进,具有丰富和强大的库,它常被称为胶水语言. Python是一种解 ...

  6. LabVIEW(十六):多列列表框控件

    1.多列列表框控件:前面板右键>列表.表格和树>多列列表框2.默认情况下只显示列首,可设置显示行首:前面板选中多列列表框右键>显示>行首3.LabVIEW中提供42种自带的图标 ...

  7. 微信开发-PC调试-JS-SDK功能之分享功能调试

    一般涉及和第三方的开发调试,都会比较麻烦些.不过,像微信这样的大公司呢,产品技术是过硬的,所以,基本上只要自己把文档看仔细了,弄好了,基本就没有问题了. 对于后端接口一类的调试,主要就是通过打印访问日 ...

  8. Spring boot 使用 configuration 获取的属性为 null

    1. 未设置 getter(),setter()方法,导致属性值注入失败: 2. spring 未扫描到该组件,在其他类中注入该对象失败,可在配置类添加 @configuration 或者 @comp ...

  9. 使用config 来管理ssh的会话

    通常利用 ssh 连接远程服务器,一般都要输入以下类型命令: ssh user@hostname -p port 如果拥有多个ssh账号,特别是像我这种喜欢在终端里直接ssh登录, 要记住每个ssh账 ...

  10. BOM 浏览器对象模型

    1.window对象模型:(操作浏览器) 它既是ECMAScript规定的global对象,又是javascript访问浏览器窗口的一个接口 系统对话框:这些对话框有操作系统/浏览器设置决定,css不 ...