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; } } }
HTML code
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Wall._Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>迷宫生成</title> <style> td{border:2px solid black;width:20px;height:20px;} body{ text-align:center;font-size:12px} div{color:Red;font-weight:bold;font-size:12px} </style> <script> var maxX=<%=maxX %>; var maxY=<%=maxY %>; var None="#ffffff"; function d(x,y) { var td1=document.getElementById("td" +x ); var td2=document.getElementById("td" +y ); if(y==x+1) { td1.style.borderRightColor=None; td2.style.borderLeftColor=None; } if(y==x+maxX) { td1.style.borderBottomColor=None; td2.style.borderTopColor=None; } } </script> </head> <body> <form id="form1" runat="server"> 每天,笨狼都要下班穿过复杂的街道去接老婆,请给笨狼指条路:) X: <asp:TextBox ID="TextBox1" runat="server" Text="40" Width="32px"></asp:TextBox><asp:RangeValidator ID="RangeValidator1" runat="server" ControlToValidate="TextBox1" ErrorMessage="必须在10和80之间" MaximumValue="80" MinimumValue="10" Type="Integer"></asp:RangeValidator> Y: <asp:TextBox ID="TextBox2" runat="server" Text="25" Width="29px"></asp:TextBox><asp:RangeValidator ID="RangeValidator2" runat="server" ControlToValidate="TextBox2" ErrorMessage="必须在10和50之间" MaximumValue="50" MinimumValue="10" Type="Integer"></asp:RangeValidator> <asp:Button ID="Button1" runat="server" Text="确定" /> <br/> <div style='text-align:left;width:<%=(maxX+8)*20%>px'><--进口</div> <table id="tb" style="border-collapse:collapse;" border=0 > <%=HTML.ToString()%> </table> <div style='text-align:right;width:<%=(maxX+8)*20%>px' > 出口--></div> <script> <%=SCRIPT.ToString()%> document.getElementById("td1").style.borderLeftColor=None; document.getElementById("td" + (maxX * maxY)).style.borderRightColor=None; document.getElementById("td1").style.backgroundColor="red"; var OK=0; for(var i=1;i<=maxX*maxY;i++) { var td=document.getElementById("td" + i); td.onmouseover=function Over(){ var id=parseInt(this.id.replace(/td/ig,'')); var Neighbor=document.getElementById("td" + (id-1)); if(Neighbor !=null) { if(Neighbor.style.backgroundColor=="red" && this.style.borderLeftColor==None) { this.style.backgroundColor="red"; } } Neighbor=document.getElementById("td" + (id-maxX)); if(Neighbor !=null) { if(Neighbor.style.backgroundColor=="red" && this.style.borderTopColor==None) { this.style.backgroundColor="red"; } } Neighbor=document.getElementById("td" + (id+1)); if(Neighbor !=null) { if(Neighbor.style.backgroundColor=="red" && this.style.borderRightColor==None) { this.style.backgroundColor="red"; } } Neighbor=document.getElementById("td" + (id+maxX)); if(Neighbor !=null) { if(Neighbor.style.backgroundColor=="red" && this.style.borderBottomColor==None) { this.style.backgroundColor="red"; } } if(this.style.backgroundColor=="red" && this.id==("td" + maxX*maxY)) { OK++; } if(OK==1) { OK++; if(window.confirm("恭喜你成功了!~~,重新玩一次吗?")) { window.location.reload(); } } } } </script> </form> </body> </html>
Random rand = new Random(input);
每次结果都产生相同的东东,这里改一下,生成就随机了。

private int randomInt(int input)

        {
            Random rand = new Random();
            //随机在全部中选择一个
            rand = new Random(rand.Next(input));
            if (input  == 0)
            {
                return 0;
            }
            else
            {
                return rand.Next(input);
            }
        }
posted on 2008-07-24 17:13  poop  阅读(374)  评论(0)    收藏  举报