Created
February 19, 2012 15:52
-
-
Save ErisianArchitect/1864399 to your computer and use it in GitHub Desktop.
Drawing algorithm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define FASTDRAW | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
//using System.Drawing; | |
using System.IO; | |
using System.Windows.Forms; | |
using Microsoft.Xna.Framework; | |
using System.Threading; | |
namespace RectTest | |
{ | |
class Program | |
{ | |
static int[,] dataMap = new int[16, 16]; | |
static bool[,] flags = new bool[16, 16]; | |
static int startX, startY; | |
static void InitMap() | |
{ | |
Random r = new Random(); | |
for (int x = 0; x < 16; x++) | |
{ | |
for (int y = 0; y < 16; y++) | |
{ | |
dataMap[x, y] = r.Next(100) >= 95 ? 1 : 0; | |
flags[x, y] = false; | |
} | |
} | |
startX = r.Next(15); | |
startY = r.Next(15); | |
dataMap[startX, startY] = 0; | |
} | |
static void ResetFlags() | |
{ | |
for (int x = 0; x < 16; x++) | |
{ | |
for (int y = 0; y < 16; y++) | |
{ | |
flags[x, y] = false; | |
} | |
} | |
} | |
static void DrawMap() | |
{ | |
Console.Clear(); | |
for (int y = 0; y < 16; y++) | |
{ | |
for (int x = 0; x < 16; x++) | |
{ | |
switch (dataMap[x, y]) | |
{ | |
case 0: | |
Console.Write(' '); | |
break; | |
case 1: | |
Console.Write('#'); | |
break; | |
case 2: | |
Console.Write('+'); | |
break; | |
} | |
} | |
Console.Write('\n'); | |
} | |
} | |
static void Run() | |
{ | |
Console.Clear(); | |
InitMap(); | |
DrawMap(); | |
ConsoleKey key = Console.ReadKey(true).Key; | |
if (key == ConsoleKey.N) | |
{ | |
Console.Clear(); | |
DateTime start = DateTime.Now; | |
FillOccluData(); | |
DateTime end = DateTime.Now; | |
Console.SetCursorPosition(0, 16); | |
Console.WriteLine("[{0},{1}]", startX, startY); | |
Console.WriteLine("{0} walls drawn in {1} milliseconds.", wallCount, end.Subtract(start).TotalMilliseconds); | |
//DrawMap(); | |
//Thread.Sleep(5000); | |
Console.ReadKey(true); | |
Run(); | |
} | |
else if (key == ConsoleKey.Escape) | |
return; | |
else | |
{ | |
Run(); | |
} | |
} | |
enum QueryType | |
{ | |
All, | |
Up, | |
Down, | |
Left, | |
Right, | |
NE, | |
SE, | |
NW, | |
SW | |
} | |
struct queryData | |
{ | |
public queryData(int x, int y, QueryType q) | |
{ | |
this.X = x; | |
this.Y = y; | |
this.query = q; | |
} | |
public int X, Y; | |
public QueryType query; | |
} | |
static void Set(int x, int y) | |
{ | |
flags[x, y] = true; | |
dataMap[x, y] = 2; | |
} | |
static void DrawWall(int x, int y) | |
{ | |
#if !FASTDRAW | |
if (x < 0 || x > 15 || y < 0 || y > 15) | |
return; | |
int xx, yy; | |
xx = Console.CursorLeft; | |
yy = Console.CursorTop; | |
Console.SetCursorPosition(x, y); | |
Console.Write('#'); | |
Console.SetCursorPosition(xx, yy); | |
#endif | |
wallCount++; | |
} | |
static int wallCount = 0; | |
static void FillOccluData() | |
{ | |
wallCount = 0; | |
Queue<queryData> que = new Queue<queryData>(); | |
que.Enqueue(new queryData(startX, startY, QueryType.All)); | |
while (que.Count > 0) | |
{ | |
queryData q = que.Dequeue(); | |
switch (q.query) | |
{ | |
case QueryType.All: | |
queryAll(q.X, q.Y, que); | |
break; | |
case QueryType.Up: | |
queryUp(q.X, q.Y, que); | |
break; | |
case QueryType.Down: | |
queryDown(q.X, q.Y, que); | |
break; | |
case QueryType.Left: | |
queryLeft(q.X, q.Y, que); | |
break; | |
case QueryType.Right: | |
queryRight(q.X, q.Y, que); | |
break; | |
case QueryType.NE: | |
queryNE(q.X, q.Y, que); | |
break; | |
case QueryType.SE: | |
querySE(q.X, q.Y, que); | |
break; | |
case QueryType.NW: | |
queryNW(q.X, q.Y, que); | |
break; | |
case QueryType.SW: | |
querySW(q.X, q.Y, que); | |
break; | |
} | |
} | |
} | |
static int canQuery(int x, int y) | |
{ | |
if (x < 0 || x > 15 || y < 0 || y > 15 || flags[x, y]) | |
return 0; | |
return dataMap[x, y] == 1 ? 2 : 1; | |
} | |
static void queryAll(int x, int y, Queue<queryData> que) | |
{ | |
switch (canQuery(x, y)) | |
{ | |
case 1: | |
Set(x, y); | |
que.Enqueue(new queryData(x, y - 1, QueryType.Up)); | |
que.Enqueue(new queryData(x + 1, y, QueryType.Right)); | |
que.Enqueue(new queryData(x, y + 1, QueryType.Down)); | |
que.Enqueue(new queryData(x - 1, y, QueryType.Left)); | |
break; | |
case 2: | |
Set(x, y); | |
DrawWall(x, y); | |
break; | |
} | |
} | |
static void queryUp(int x, int y, Queue<queryData> que) | |
{ | |
switch (canQuery(x, y)) | |
{ | |
case 1: | |
Set(x, y); | |
que.Enqueue(new queryData(x, y - 1, QueryType.Up)); | |
que.Enqueue(new queryData(x - 1, y, QueryType.NW)); | |
que.Enqueue(new queryData(x + 1, y, QueryType.NE)); | |
break; | |
case 2: | |
Set(x, y); | |
DrawWall(x, y); | |
break; | |
} | |
} | |
static void queryDown(int x, int y, Queue<queryData> que) | |
{ | |
switch (canQuery(x, y)) | |
{ | |
case 1: | |
Set(x, y); | |
que.Enqueue(new queryData(x, y + 1, QueryType.Down)); | |
que.Enqueue(new queryData(x - 1, y, QueryType.SW)); | |
que.Enqueue(new queryData(x + 1, y, QueryType.SE)); | |
break; | |
case 2: | |
Set(x, y); | |
DrawWall(x, y); | |
break; | |
} | |
} | |
static void queryLeft(int x, int y, Queue<queryData> que) | |
{ | |
switch (canQuery(x, y)) | |
{ | |
case 1: | |
Set(x, y); | |
que.Enqueue(new queryData(x - 1, y, QueryType.Left)); | |
que.Enqueue(new queryData(x, y - 1, QueryType.NW)); | |
que.Enqueue(new queryData(x, y + 1, QueryType.SW)); | |
break; | |
case 2: | |
Set(x, y); | |
DrawWall(x, y); | |
break; | |
} | |
} | |
static void queryRight(int x, int y, Queue<queryData> que) | |
{ | |
switch (canQuery(x, y)) | |
{ | |
case 1: | |
Set(x, y); | |
que.Enqueue(new queryData(x + 1, y, QueryType.Right)); | |
que.Enqueue(new queryData(x, y - 1, QueryType.NE)); | |
que.Enqueue(new queryData(x, y + 1, QueryType.SE)); | |
break; | |
case 2: | |
Set(x, y); | |
DrawWall(x, y); | |
break; | |
} | |
} | |
static void queryNE(int x, int y, Queue<queryData> que) | |
{ | |
switch (canQuery(x, y)) | |
{ | |
case 1: | |
Set(x, y); | |
que.Enqueue(new queryData(x, y - 1, QueryType.NE)); | |
que.Enqueue(new queryData(x + 1, y, QueryType.NE)); | |
break; | |
case 2: | |
Set(x, y); | |
DrawWall(x, y); | |
break; | |
} | |
} | |
static void querySE(int x, int y, Queue<queryData> que) | |
{ | |
switch (canQuery(x, y)) | |
{ | |
case 1: | |
Set(x, y); | |
que.Enqueue(new queryData(x, y + 1, QueryType.SE)); | |
que.Enqueue(new queryData(x + 1, y, QueryType.SE)); | |
break; | |
case 2: | |
Set(x, y); | |
DrawWall(x, y); | |
break; | |
} | |
} | |
static void queryNW(int x, int y, Queue<queryData> que) | |
{ | |
switch (canQuery(x, y)) | |
{ | |
case 1: | |
Set(x, y); | |
que.Enqueue(new queryData(x, y - 1, QueryType.NW)); | |
que.Enqueue(new queryData(x - 1, y, QueryType.NW)); | |
break; | |
case 2: | |
Set(x, y); | |
DrawWall(x, y); | |
break; | |
} | |
} | |
static void querySW(int x, int y, Queue<queryData> que) | |
{ | |
switch (canQuery(x, y)) | |
{ | |
case 1: | |
Set(x, y); | |
que.Enqueue(new queryData(x, y + 1, QueryType.SW)); | |
que.Enqueue(new queryData(x - 1, y, QueryType.SW)); | |
break; | |
case 2: | |
Set(x, y); | |
DrawWall(x, y); | |
break; | |
} | |
} | |
static void Main(string[] args) | |
{ | |
Run(); | |
} | |
} | |
//public class Grid | |
//{ | |
// #region Properties | |
// public Point BoxSize = new Point(8, 8), Offset = Point.Empty; | |
// #endregion | |
// #region Methods | |
// public Point Snap(Point input) | |
// { | |
// Snap(input, out input); | |
// return input; | |
// } | |
// public void Snap(Point input, out Point result) | |
// { | |
// int x = input.X - Offset.X; | |
// int y = input.Y - Offset.Y; | |
// x = x - x % BoxSize.X; | |
// y = y - y % BoxSize.Y; | |
// result = new Point(x + Offset.X, y + Offset.Y); | |
// } | |
// #endregion | |
//} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment