zoukankan      html  css  js  c++  java
  • C#迷宫生成的算法 转

    1,利用C#自带的几种集合类可以用来描述集合的概念,比如{1,2},{3,4,5}可以用List<List<int>>来表示集合的集合
    2,所谓迷宫,并不是随机生成路其他的围墙,而是如何拆墙。比如{1,2},{3,4,5}拆掉2和3只间的墙,就形成了{1,2,3,4,5}
    最初的格子状态就是{1},{2},{3},{4}.....如果随机找到2集合,再把其中的墙随机挑选一个拆掉,直到全部集合连通成一个几何,迷宫就生成完毕。
    3,不需要递归,递归可能会带来低效率,如果可以不用就不用。
    4,如果需要在集合里快速查找一个数据,建议用Dictionary<>,因为他查找一个Key的复杂度是O(1),如果在集合里随机挑选一个东东,用List<T>比较方便。
    5,效果见http://www.dullwolf.cn/Wall/
    6,代码还可以优化,有兴趣的同学试验一下:)

    C# code

    using System;
    using System.Collections.Generic;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Text;

    namespace Wall
    {
    public partial class _Default : System.Web.UI.Page
    {
    protected StringBuilder HTML = new StringBuilder();
    protected StringBuilder SCRIPT = new StringBuilder();
    private List<List<int>> totalWays = new List<List<int>>();
    private Dictionary<string, bool> allWalls = new Dictionary<string, bool>();
    private Dictionary<string, bool> deleteWalls = new Dictionary<string, bool>();
    protected int maxX;
    protected int maxY;
    protected void Page_Load(object sender, EventArgs e)
    {
    HTML.Append("");
    maxX = Convert.ToInt32(this.TextBox1.Text);
    maxY = Convert.ToInt32(this.TextBox2.Text);

    for (int y = 0; y < maxY; y++)
    {
    HTML.Append("<tr>" );
    for (int x = 1; x <= maxX; x++)
    {
    int id = x + y * maxX;
    List<int> room = new List<int>();
    room.Add(id);
    totalWays.Add(room);
    string theWall = makeWall(id, id + 1);
    if (x < maxX) { allWalls.Add(theWall,true); }
    theWall = makeWall(id, id + maxX);
    if (y < maxY) { allWalls.Add(theWall, true); }
    HTML.Append("<td id=td" + id + ">" + " </td>");
    }
    HTML.Append("</tr>");
    }
    while (totalWays.Count > 1)
    {
    makePuzzle();
    }
    foreach (string Key in deleteWalls.Keys)
    {
    SCRIPT.Append("d(" + Key + ");");
    }
    }
    private void makePuzzle()
    {
    //随机在全部中选择一个回廊
    int firstChoice = randomInt(totalWays.Count);
    //列出该回廊全部相关回廊;
    List<int> firstChoiceWay = totalWays[firstChoice];
    List<List<int>> tempWay = new List<List<int>>();
    for (int i = 0; i < totalWays.Count; i++)
    {
    if (i != firstChoice)
    {
    if (isNeighbor(firstChoiceWay, totalWays[i]))
    {
    tempWay.Add(totalWays[i]);
    //break;
    }
    }
    }
    //随机在totalWays中选择一个回廊
    int secondChoice = randomInt(tempWay.Count);
    List<int> secondCoiceWay = tempWay[secondChoice];
    //得到2者间全部可以拆的墙
    List<string> tempWalls = new List<string>();
    for (int i = 0; i < firstChoiceWay.Count; i++)
    {
    for (int j = 0; j < secondCoiceWay.Count; j++)
    {
    if (IsExsists(firstChoiceWay[i], secondCoiceWay[j]))
    {
    tempWalls.Add(makeWall(firstChoiceWay[i], secondCoiceWay[j]));
    }
    }
    }
    int thirdChoice = randomInt(tempWalls.Count);
    string theWall = tempWalls[thirdChoice];
    //纪录拆墙办法
    deleteWalls.Add(theWall,true);
    //增加一个新的
    List<int> newWay = new List<int>();
    newWay.AddRange(firstChoiceWay);
    newWay.AddRange(secondCoiceWay);
    totalWays.Add(newWay);
    //移掉2个
    totalWays.Remove(firstChoiceWay);
    totalWays.Remove(secondCoiceWay);
    allWalls.Remove(theWall);
    }

    private string makeWall(int x, int y)
    {
    if (x > y)
    {
    return y.ToString() + "," + x;
    }
    else
    {
    return x.ToString() + "," + y;
    }
    }
    private int randomInt(int input)
    {
    Random rand = new Random(input);
    //随机在全部中选择一个
    //得到回廊的回廊
    if (input == 0)
    {
    return 0;
    }
    else
    {
    return rand.Next(0, input);
    }
    }


    /// <summary>
    /// 判断两个集合是否是邻居
    /// </summary>
    /// <param name="a"></param>
    /// <param name="b"></param>
    /// <returns></returns>
    private bool isNeighbor(List<int> a, List<int> b)
    {
    bool re = false;
    for (int i = 0; i < a.Count; i++)
    {
    for (int j = 0; j < b.Count; j++)
    {
    if (IsExsists(a[i], b[j]))
    {
    re = true;
    break;
    }
    }
    if (re) { break; }
    }
    return re;
    }
    private bool IsExsists(int x, int y)
    {
    bool re = false;
    if (Math.Abs(x-y) == 1 || Math.Abs(x-y) == maxX)
    {
    string theWall = makeWall(x,y);
    if (allWalls.ContainsKey(theWall))
    {
    re = true;
    }
    }
    return re;
    }
    }
    }
  • 相关阅读:
    Swift的闭包(一):闭包简介、闭包表达式的优化
    iOS 用户体验之音频
    【iOS】Core Bluetooth
    【iOS】3D Touch
    golang中channel的超时处理
    Objective-C 中的 BOOL
    2015年总结
    load vs. initialize
    正则表达式
    When does layoutSubviews get called?
  • 原文地址:https://www.cnblogs.com/liye/p/1713153.html
Copyright © 2011-2022 走看看