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;
    }
    }
    }
  • 相关阅读:
    程序员的7中武器
    需要强化的知识
    微软中国联合小i推出MSN群Beta 不需任何插件
    XML Notepad 2006 v2.0
    Sandcastle August 2006 Community Technology Preview
    [推荐] TechNet 广播 SQL Server 2000完结篇
    《太空帝国 4》(Space Empires IV)以及 xxMod 英文版 中文版 TDM Mod 英文版 中文版
    IronPython 1.0 RC2 更新 1.0.60816
    Microsoft .NET Framework 3.0 RC1
    《Oracle Developer Suite 10g》(Oracle Developer Suite 10g)V10.1.2.0.2
  • 原文地址:https://www.cnblogs.com/liye/p/1713153.html
Copyright © 2011-2022 走看看