Skip to content

Instantly share code, notes, and snippets.

@ErisianArchitect
Created February 19, 2012 15:52
Show Gist options
  • Save ErisianArchitect/1864399 to your computer and use it in GitHub Desktop.
Save ErisianArchitect/1864399 to your computer and use it in GitHub Desktop.
Drawing algorithm
#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